У меня есть многопользовательская игра, которая читает данные XML с сервера:
_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);
}
}
В большинстве случаев это работает нормально, но иногда пользователи жалуются, что игра зависает для них.Они могут отправлять команды на сервер, но из их описаний я подозреваю, что приведенная выше функция не работает для них, и updateGUI()
перестает вызываться.
Эта проблема трудна для отладки... Я думаю, что мой сервер (в Perl / C, не разветвленный, использует poll ()) работает хорошо, я должен делать что-то не так со стороны Flash.
Это хорошая идея для вызова readUTF()
здесь?Вполне может случиться так, что только часть строки UTF прибудет, и тогда фильм Flash остановится в readUTF()
, не так ли?(Я никогда этого не видел)
ОБНОВЛЕНИЕ:
Да, спасибо, мне нужно поймать EOFError
, также у меня есть хороший совет всписок рассылки, который я должен прочитать _socket.bytesAvailable
байт в ByteArray
и работать с этим (проверьте, пришло ли мое полное сообщение) - все остальное ненадежно.
Так что я придумал это, но все жеесть недостаток:
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;
}
}
- , когда доступно слишком много байтов, например, 800, а мои сообщения имеют длину только 400 байтов, то он застревает.
Также мне интересно, можно ли улучшить копирование оставшихся байтов (то есть, не выделяя каждый раз новый ByteArray)?
Я могу воспроизводить этот недостаток часто, к счастью