skaarj1989/mWebSockets

server closes the websocket after 5 seconds

stevstrong opened this issue · 6 comments

HI,
I am using the simple server example from your repo for STM32 architecture and W5500 module combined with the stock Ethernet library.
I have the problem that 5 seconds after I start the client application (Firefox on my PC) the client reports that the websocket is closed by the server (this example).

Digging into the code I arrived to WebSocketServer.cpp:

EthernetClient client = m_server.available();
if (client && client.available()) {
WebSocket *ws{ _getWebSocket(client) };
if (!ws) {
const auto end = &m_sockets[kMaxConnections];
for (auto it = &m_sockets[0]; it != end; ++it) {
if (!(*it)) {
if (_handleRequest(client)) {
*it = new WebSocket(client);
ws = *it;
if (_onConnection) _onConnection(*ws);
}
break;
}
}
// Server is full ...
if (!ws) _rejectRequest(client, WebSocketError::SERVICE_UNAVAILABLE);
}
if (ws) ws->_readFrame();

In particular, it seems that line 91 should be only called in the else case of line 74 condition. Otherwise, as it currently is, for the first time when ws is NULL, in line 74, ws will be non-null in line 80 but there are no available data to read, so that the websocket _read() function (see here) called by _readFrame in line 91 will timeout exactly after 5 seconds.

Changing the above mentioned code line in the following way solves the problem:

    if (!ws) {
      const auto end = &m_sockets[kMaxConnections];
      for (auto it = &m_sockets[0]; it != end; ++it) {
        if (!(*it)) {
          if (_handleRequest(client)) {
            *it = new WebSocket(client);
            ws = *it;
            if (_onConnection) _onConnection(*ws);
          }
          break;
        }
      }

      // Server is full ...
      if (!ws) _rejectRequest(client, WebSocketError::SERVICE_UNAVAILABLE);
    } else {
      ws->_readFrame(); // no need to check (ws) again, in line 74 was already checked to be non-null
    }

Please let me know if this change makes sense, at least for me it works.

Hi @stevstrong,
I could not reproduce your issue on my NUCLEO-L152RE (at least with this chat-client.htm)

  1. Which STM32 do you have?
  2. Can you share your client code?
  3. Please attach server debug log

Hi David,

thanks for your reply.

The problem can be observed only if you do not send any message from the client to server in the first 5 seconds after establishing the socket channel.

I was using this example: https://github.com/stevstrong/mWebSockets/tree/master/examples/server-LEDcontrol, and in particular this HTML file. It has no external dependencies, it is a very simple client which is mostly waiting for messages from the server and updates the status of the LED dependent on the received messages. Data will be only sent if you change the LED off or on time.

Btw, the same error case could be reproduced with your client:
image
(the second line comes from my server)

EDIT
And the server ends up with the message: WS disconnected, reason:
You could make the case visible if you add for example printf("*"); to this line: https://github.com/skaarj1989/mWebSockets/blob/master/src/WebSocket.cpp#L233.
I added this serial print: https://github.com/stevstrong/mWebSockets/blob/0d15edf759ec88190412b817df21504f118c1e99/src/WebSocket.cpp#L206-L207 and the serial monitor shows a nice long line ...

In my case, disconnection happens for every 2nd client. You are right, that little else makes difference ;)
I'll update master branch if autobahn testsuite will show me green for every supported platform.
Thanks for your contribution.

Welcome, I think this solves eventually some closed but not 100% understood issues, I hope that others can benefit from this.

Master branch updated.