[Gambas-user] gb3: using string as stream for sequential write operations of arbitrary datatypes
Kevin Fishburne
kevinfishburne at ...1887...
Tue Aug 30 07:52:59 CEST 2011
Crap, I accidentally sent this to the man himself instead of the mailing
list. Sorry about that Benoît.
I'm implementing client-server network transaction histories so that
transactions which are sent but aren't answered by an acknowledgment
(dropped/lost) are resent. I don't want to have to recreate the
transaction payloads however, but simply resend a copy of what was
originally sent. Here's an example of what I'm doing (edited and
condensed for legibility):
Public Sub UDP_Write_120(ip As String, port As Integer, id As Byte,
player As Short, worldx As Single, worldy As Single)
' Send "players data update, world coordinates, one player"
transaction to specified IP address and port over UDP.
' Define target's IP address and port.
udp.TargetHost = ip
udp.TargetPort = port
' Send transaction.
udp.Begin
Write #udp, id As Byte
Write #udp, 120 As Byte
Write #udp, player As Short
Write #udp, worldx As Single
Write #udp, worldy As Single
udp.Send
' Add to transaction history.
UDP_Write_Finish(ip, port, id, 120)
End
The recipient will receive a string (data) which I break down into
separate variables using the code:
' Parse UDP data and assign to variables.
id = Read #udp As Byte
type = Read #udp As Byte
If Eof(udp) = False Then data = Read #udp, Lof(udp)
' Parse UDP data and add to client's server transaction queue.
Client.QueueIn[id].Type = type ' Type.
Client.QueueIn[id].Data = data ' Data
' New transaction found, assign its data to variables.
tstype = QueueIn[tspos].Type ' Type.
tsdata = QueueIn[tspos].Data ' Data.
' Update another player's position from the transaction queue.
pposition[Short@(Convert.Reverse(Mid$(tsdata, 1, 2))), 0] =
Single@(Convert.Reverse(Mid$(tsdata, 3, 4)))
pposition[Short@(Convert.Reverse(Mid$(tsdata, 1, 2))), 1] =
Single@(Convert.Reverse(Mid$(tsdata, 7, 4)))
All this works extremely well. The problem is when I try to store the
payload (player, worldx, worldy) for the outgoing transaction in the
transaction history. When writing variables to the network socket, a
string containing the variables is received by the recipient which I can
parse. I need to add that string to the transaction history of the
sender. The "UDP_Write_Finish()" procedure mentioned looks like this:
Public Sub UDP_Write_Finish(ip As String, port As Integer, id As Byte,
type As Byte)
' Perform post-write tasks. Called after a transaction has been sent.
' General declarations.
Dim Player As Short
' Determine client/server mode.
If mode = "server" Then
' Look up player number.
Player = Server.Player_Find_IP(ip)
' Add transaction to server's outgoing transaction queue.
Server.QueueOut[Player, id].Acknowledged = False
Server.QueueOut[Player, id].Timestamp = Timer
Server.QueueOut[Player, id].Type = type
Server.QueueOut[Player, id].Data = ???
' Increment the server transaction ID for the client.
Server.Increment_ID(Player)
' Display debug info.
Console.Say("Sent to client " & ip & ", Port: " & port & ", ID: " &
id & ", Type: " & type)
Else
' Add transaction to client's outgoing transaction queue.
Client.QueueOut[id].Acknowledged = False
Client.QueueOut[id].Timestamp = Timer
Client.QueueOut[id].Type = type
Client.QueueOut[id].Data = ???
' Increment the client transaction ID.
Client.Increment_ID
' Display debug info.
Console.Say("Sent to server " & ip & ", Port: " & port & ", ID: " &
id & ", Type: " & type)
Endif
End
When a transaction isn't received and I need to resend it, I'd like to
be able to refer to the transaction history and resend the data
(QueueOut[id].Data) without having to recalculate it, especially since
the data may have changed during the timeout period. I don't see any way
to store a completely arbitrary set of datatypes as a single structure
property however. I could write them to a file, then read the file into
a string and load it into a property of the array of structures, but
that's just crazy.
As you may remember the converse of the [datatype]@ functions solved
this problem but were removed from gb3. If any other solution is
available I'd like to hear about it. The subject line of the email is
one suggestion, though I don't know if it's possible. If it is possible
then I could create a string from arbitrary variables, send the string
via UDP and archive it in the transaction history. Any insight is
appreciated, as always.
--
Kevin Fishburne
Eight Virtues
www: http://sales.eightvirtues.com
e-mail: sales at ...1887...
phone: (770) 853-6271
More information about the User
mailing list