Note that there are some explanatory texts on larger screens.

plurals
  1. PObytesAvailable, readUTF() and ProgressEvent.SOCKET_DATA
    primarykey
    data
    text
    <p>I have a multiplayer game, which reads XML data from the server:</p> <pre><code> _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); } } </code></pre> <p>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 <code>updateGUI()</code> stops being called.</p> <p>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.</p> <p>Is it a good idea to call <code>readUTF()</code> here? It could well be that only part of the UTF string arrives and then the Flash movie would freeze in <code>readUTF()</code>, wouldn't it? (I've never seen that though)</p> <p><strong>UPDATE:</strong></p> <p>Yes thanks, I need to catch <code>EOFError</code>, also I've got a good advise in a mailing list that I must read <code>_socket.bytesAvailable</code> bytes into a <code>ByteArray</code> and work with that (check if my complete message arrived) - anything else is unreliable.</p> <p>So I've come up with this, but still have a flaw there:</p> <pre><code>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 &gt;= 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 &gt;= 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; } } </code></pre> <ul> <li>when there are too many bytes available, for example 800 and my messages are only 400 bytes long, then it stucks.</li> </ul> <p>Also I wonder, if copying remaining bytes could be improved (i.e. without allocating a new ByteArray each time)?</p> <p>I can reproduce this flaw often, luckily</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload