1

I have to integrate a WebsocketServer into an existing Air-AS3-Project. We decided to use the server implementation here ( https://github.com/childoftv/as3-websocket-server ) Now everything works fine when connecting and sending smaller payloads. However, once we try to send a large-ish payload the client disconnects with a mere Websocket Error 1006 ( closed abnormally ) and the server broadcasts a client disconnected error.

This is the code within the server implementation which handles the message sending:

        public function sendMessage(clientSocket:Socket,msg:String,continuation:Boolean=false):void
    {
        if( clientSocket != null && clientSocket.connected )
        {
            var rawData:ByteArray=new ByteArray()
            var indexStartRawData:uint;
            rawData.writeUTFBytes( msg );
            rawData.position=0;
            var bytesFormatted:Array=[];
            
            if(continuation)
            {
                bytesFormatted[0] = 128;
            }else{
                //Text Payload
                bytesFormatted[0] = 129; 
            }
            
            if (rawData.length <= 125)
            {
                bytesFormatted[1] = rawData.length;
                
                //indexStartRawData = 2;
            }else if(rawData.length >= 126 && rawData.length <= 65535){
                
                
                bytesFormatted[1] = 126
                bytesFormatted[2] = ( rawData.length >> 8 ) & 255
                bytesFormatted[3] = ( rawData.length) & 255
                
                //indexStartRawData = 4
            }else{
                
                bytesFormatted[1] = 127
                bytesFormatted[2] = ( rawData.length >> 56 ) & 255
                bytesFormatted[3] = ( rawData.length >> 48 ) & 255
                bytesFormatted[4] = ( rawData.length >> 40 ) & 255
                bytesFormatted[5] = ( rawData.length >> 32 ) & 255
                bytesFormatted[6] = ( rawData.length >> 24 ) & 255
                bytesFormatted[7] = ( rawData.length >> 16 ) & 255
                bytesFormatted[8] = ( rawData.length >>  8 ) & 255
                bytesFormatted[9] = ( rawData.length       ) & 255
                
                //indexStartRawData = 10;
            }
            
            
            // put raw data at the correct index
            var dataOut:ByteArray=new ByteArray();
            
            for(var i:uint=0;i<bytesFormatted.length;i++)
            {
                dataOut.writeByte(bytesFormatted[i]);
            }
            
            dataOut.writeBytes(rawData);
            dataOut.position=0;
            clientSocket.writeBytes(dataOut);
            clientSocket.flush(); 
            log( "Sent message to "+getClientKeyBySocket(clientSocket)+" msg="+msg);
        }else{
            log("No socket connection.");
        }
    }

I am having some trouble wrapping my head around this. Any pointers highly appreciated.

zantafio
  • 677
  • 6
  • 20
  • Most obvious workaround: did you try to split the output data into smaller chunks to send them out over a course of several frames? – Organis Dec 20 '20 at 13:56
  • Yes, I did. However I'd still like to learn and understand where the issue might be and how to make it work. – zantafio Dec 21 '20 at 09:34
  • Did you figure out the definite threshold between "it's ok" and "too much" amount of data? Maybe, server has some settings on that? – Organis Dec 21 '20 at 09:46
  • there is unfortunately no setting on the server. I did a test and noticed that the error occurs once the payload exceeeds 65535 bytes and the code runs through the last case. – zantafio Dec 21 '20 at 11:15
  • Well, poke at this, at least: the **rawData.length** is an unsigned 32-bit integer, you treat it as 64-bit integer. Also, maybe, this: https://stackoverflow.com/questions/2613734/maximum-packet-size-for-a-tcp-connection#:~:text=10%20Answers&text=The%20absolute%20limitation%20on%20TCP,for%20instance%2C%20is%201500%20bytes. – Organis Dec 21 '20 at 13:24
  • Hm. I am not sure if I follow. The code above is not from me but from the library. Where is rawData.length treated as 64-bit integer? – zantafio Dec 21 '20 at 13:48
  • At the block where it is recorded into **bytesFormatted** as 8 bytes of data (>> 56 then >> 48 etc) rather than 4. – Organis Dec 21 '20 at 13:55

0 Answers0