Hello,
I have multiplayer game, which reads XML data from the server:
_socket = new Socket();
_socket.addEventListener(ProgressEvent.SOCKET_DATA, handleTcpData);
.....
private function handleTcpData(event:Event):void {
while (_socket.bytesAvailable) {
var str:String = _socket.readUTF();
updateGUI(str);
}
}
In most cases it works ok, but sometimes users complain that the game hangs for them. They are able to send in commands to the server, but from their descriptions I suspect, that the function above doesn't work well for them and the updateGUI() stops being called.
This issue is difficult to debug... I think my server (in Perl/C, non-forking, uses poll()) works well, I must be doing something wrong at the Flash side.
Is it a good idea to call readUTF() here? It could well be that only part of the UTF string arrives and then the Flash movie would freeze in readUTF(), wouldn't it? (I've never seen that though)
Regards Alex
UPDATE:
Yes thanks, I need to catch EOFError, also I've got a good advise in a mailing list that I must read _socket.bytesAvailable bytes into a ByteArray and work with that (check if my complete message arrived) - anything else is unreliable.
So I've come up with this, but still have a flaw there:
private function handleTcpData(event:Event):void {
var len:uint;
if (0 == _socket.bytesAvailable)
return;
try {
_socket.readBytes(_ba, _ba.bytesAvailable, _socket.bytesAvailable);
// read the length of the UTF string to follow
while (_ba.bytesAvailable >= 2) {
len = _ba.readUnsignedShort();
// invalid length - reset
if (0 == len) {
trace('XXX invalid len = ' + len);
_ba.position = 0;
_ba.length = 0;
return;
}
if (_ba.bytesAvailable >= len) {
var str:String = _ba.readUTFBytes(len);
updateGUI(str);
// copy the remaining bytes
// (does it work? can it be improved?)
var newBA:ByteArray = new ByteArray();
newBA.readBytes(_ba);
_ba = newBA;
}
}
} catch(e:Error) {
trace('XXX ' + e);
_ba.position = 0;
_ba.length = 0;
return;
}
}
- when there are too many bytes available, for example 800 and my messages are only 400 bytes long, then it stucks.
Also I wonder, if copying remaining bytes could be improved (i.e. without allocating a new ByteArray each time)?
I can reproduce this flaw often, luckily