WebSocket receiving mangled messages

Discussion to talk about software related topics only.
AndrewS
Posts: 8
Joined: Thu Nov 23, 2017 1:04 am

WebSocket receiving mangled messages

Post 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.
User avatar
mlara
Posts: 8
Joined: Tue Mar 29, 2016 10:40 am

Re: WebSocket receiving mangled messages

Post 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?
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: WebSocket receiving mangled messages

Post 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..
AndrewS
Posts: 8
Joined: Thu Nov 23, 2017 1:04 am

Re: WebSocket receiving mangled messages

Post 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
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: WebSocket receiving mangled messages

Post by pbreed »

Why do you have to wait a second?
try using select .... should not have to wait at all...
AndrewS
Posts: 8
Joined: Thu Nov 23, 2017 1:04 am

Re: WebSocket receiving mangled messages

Post by AndrewS »

Because Im sending messages with one second interval. Can you please tell me how to use select?
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: WebSocket receiving mangled messages

Post 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....
AndrewS
Posts: 8
Joined: Thu Nov 23, 2017 1:04 am

Re: WebSocket receiving mangled messages

Post 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.
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: WebSocket receiving mangled messages

Post 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
AndrewS
Posts: 8
Joined: Thu Nov 23, 2017 1:04 am

Re: WebSocket receiving mangled messages

Post 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.
Post Reply