Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocket message won't be handled when sending too fast #556

Open
nd1012 opened this issue Apr 16, 2022 · 0 comments
Open

WebSocket message won't be handled when sending too fast #556

nd1012 opened this issue Apr 16, 2022 · 0 comments

Comments

@nd1012
Copy link

nd1012 commented Apr 16, 2022

Describe the bug
I use the EmbedIO WebSocket module and the ClientWebSocket in a local unit testing environment (server and client within the same process, everything runs asynchronous). When I use the ClientWebSocket to connect to the server and send a message directly after the ConnectAsync method returned, this message may not be processed by the EmbedIO WebSocket module.

To avoid this behavior, I had to change the protocol and send an empty message within the OnClientConnectedAsync. When the client is waiting for this empty message and starts sending after it was received, the OnMessageReceivedAsync at the server side is being executed as expected.

To Reproduce
Steps to reproduce the behavior:

  1. Run an EmbedIO WebSocket server in one thread
  2. Connect using a ClientWebSocket in another thread on the same computer (I used a thread within the same process)
  3. Send a message to the server as soon as the ClientWebSocket.ConnectAsync method returned
  4. At the server side, the OnMessageReceivedAsync may not be executed for the first message(s)

Expected behavior
At the client side I (as a naive user) actually assume that after connected, the server is able to process sent messages. When I look into the source of the WebSocketModule source, I find the connection process in the OnRequestAsync method. This method accepts the WebSocket using AcceptWebSocketAsync, then does tidy actions, then stores the context, then calls the OnClientConnectedAsync method and finally runs the message processing loop. Between AcceptWebSocketAsync and message loop processing is a time gap where no messages will be processed, which results in a timing problem, when a fast client starts sending messages directly after the WebSocket connection has been established successfully.

As I understand, the ProcessEmbedIOContext was used as message loop processor in my case. In this method an OnMessage event handler will be attached for processing received messages. This happens after the client was able to send messages already. If the AcceptWebSocketAsync would be executed after the OnMessage handler has been attached, the timing problem should be solved.

Anyway, the timing problem may not happen with slow clients (f.e. LAN or WAN connected peers). For all other cases, an empty message from the server could signal to the client that the server is ready for processing messages, after the connection has been established (as a workaround).
The RFC says in the handshake sections, the server can start processing messages after confirming the OPEN state. If you stick to it, you're doing it right, and the timing problem is a part of the RFC. In this case the client should never be the peer that starts sending messages.

System environment

  • Windows 10 64bit
  • Visual Studio 2022
  • MS Test Project (C#)
  • EmbedIO NuGet version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant