Page 1 of 2

WebSocket receiving mangled messages

Posted: Tue Nov 28, 2017 6:37 am
by AndrewS
I'm using MOD54415. I've slightly modified the \StandardStack\WebSockets\Echo\ example so that it sends messages with an interval of 1 second:

Code: Select all

// From index.htm

function WebSocketTest()
{
  if ("WebSocket" in window)
  {
     // Let us open a web socket
     var ws = new WebSocket("ws://<!--VARIABLE IPCAST(GetSocketLocalAddr4(fd)) -->/echo");
     ws.onopen = function()
     {
        // Web Socket is connected, send data using send()
		setInterval(function sendMsg() {ws.send("Message to send")}, 1000);
     };
     ws.onmessage = function (evt) 
     { 
        var received_msg = evt.data;
     };
     ws.onclose = function()
     { 
        // websocket is closed.
     };
  }
  else
  {
     // The browser doesn't support WebSocket
     alert("WebSocket NOT supported by your Browser!");
  }
}
The problem is that read() function in UserMain() while loop sometimes returns incomplete message (namely "Message is sen"). Wireshark failing to recognize this TCP packet as a WebSocket message. The only difference with the normal one is absence of last byte. Even WS payload length (second byte in TCP payload) is still equals to 15 which is incorrect. Chrome's Developer Tools shows this outgoing message have been sent without any deformation.

Any idea of what's going wrong and how to fix it?

Thank you.

Re: WebSocket receiving mangled messages

Posted: Wed Nov 29, 2017 11:20 am
by mlara
Are you capturing the WebSocket handshake in your Wireshark capture? If not, Wireshark won't recognize the packets as WebSocket packets but TCP packets instead.

Is the whole message (WebSocket payload) and length correct in the packets that Wireshark captures?

Re: WebSocket receiving mangled messages

Posted: Wed Nov 29, 2017 11:22 am
by pbreed
Just had shoulder surgery so typing oine hand thus terse replies.......

Its possible that the message is getting split into multiple websocket frames......

If you read you get 1 or more chars... so "this is a message" could be returned as...

read ->t
read ->h
read ->i
read ->s
read ->' '
read ->i
read ->s.....

one has to do framing outside of read....

just like tcp.... chars are guarenteed to be correct and in order, but not grouped in any particular way...
After you read your partial message my guess is if you read again youll get the missing parts..

Re: WebSocket receiving mangled messages

Posted: Thu Nov 30, 2017 2:02 am
by AndrewS
Yes, I'm starting packet capture before opening WebSocket and Wireshark recognizes most of the WS messages, and their payload and length are correct.

Maybe it has to do with some TCP optimization algorithm (Nagle?), I've tried NB::WebSocket::ws_setoption(ws_fd, SO_NONAGLE); but it seems not helping much. It's kinda bad that I have to wait 1 second for next packet to get that last char to complete previous message. BTW I've noticed that only one last char can be clipped, so its always either
  • Message to send
    Message to send
or
  • Message to sen
    dMessage to send

Re: WebSocket receiving mangled messages

Posted: Thu Nov 30, 2017 6:36 am
by pbreed
Why do you have to wait a second?
try using select .... should not have to wait at all...

Re: WebSocket receiving mangled messages

Posted: Thu Nov 30, 2017 7:03 am
by AndrewS
Because Im sending messages with one second interval. Can you please tell me how to use select?

Re: WebSocket receiving mangled messages

Posted: Thu Nov 30, 2017 12:07 pm
by pbreed
Lets cover some things....

These messages are going from browser to netburner. correct?

How are you reading them on the netburner side?, exactly what code are you running....

Re: WebSocket receiving mangled messages

Posted: Fri Dec 01, 2017 12:40 am
by AndrewS
That's correct.

I'm using almost the same code as in the Echo example.

Code: Select all

    while (1)
    {
        OSSemPend( &waitingForWS, 0 );

        while (ws_fd > 0) {
            FD_SET(ws_fd, &read_fds);
            FD_SET(ws_fd, &error_fds);
            select(1, &read_fds, NULL, &error_fds, 0);
            if (FD_ISSET(ws_fd, &error_fds)) {
                iprintf("Closing Socket\r\n");
                OSTimeDly(1);
                close(ws_fd);
                ws_fd = -1;
                iprintf("Socket Closed\r\n");
                break;
            }
            if (FD_ISSET(ws_fd, &read_fds)) {
                int n = read( ws_fd, (char *)pp->pData, ETHER_BUFFER_SIZE );
                n = writeall( 1, (char *)pp->pData, n );
                iprintf("\n");
                n = writeall( ws_fd, (char *)pp->pData, n );
                NB::WebSocket::ws_flush( ws_fd );
            }
            FD_ZERO( &read_fds );
            FD_ZERO( &error_fds );
        }
        OSTimeDly(TICKS_PER_SECOND * 1);
    }
I can see select() right there, but can't figure out what I can do with it.

Re: WebSocket receiving mangled messages

Posted: Fri Dec 01, 2017 7:37 am
by pbreed
Remove the
OSTimeDly(TICKS_PER_SECOND * 1)

/this is where your one second delay is comming from...

The system will pend on the select so other tasks can run....


Now your next issue is that your going to see your message show up in pieces in multiple reads....(just like you would with TCP)

So you need to reassemble the message..

Paul

Re: WebSocket receiving mangled messages

Posted: Mon Dec 04, 2017 6:33 am
by AndrewS
I've removed it, but it does not help.

The problem is that I'm getting wrong WebSocket header: header says that the payload length is N and the FIN bit is set, but actual payload length is N -1. I'll get this last byte only with next frame. But I can't even know that the message I'm receiving is incomplete because of the FIN = 1.

Say I need to read messages from client every 10 seconds. When this fragmentation occurs, I'll wait for last byte 10 seconds, cause it will be received only with next client's message. Thus, it will be 20 seconds for one message in total, when it should be 10.