River Tam
River Tam

Reputation: 3216

How can I capture failed WebSocket messages?

I'm writing a server that wants to make sure it replies to all responses if possible. If a socket disconnects, when it reconnects with the old session ID, I want the server to re-send the packets that should have gone over the socket.

However, as far as I can tell, there's no way to properly detect asynchronous errors, which is to say errors that occur at the network level. WebSocket#send throws an error if we already know that the WebSocket is in an invalid state, but if the client were to disconnect while the message was in the queue, I believe (hope) JavaScript would have already moved on.

There is an error event, but I see no way of associating it with the messages that I've tried to send.

I'm trying to do something like this:

const ws = new WebSocket(...);
// ... ensure the WebSocket is open at some point
// and we can assume `ws.readyState === WebSocket.OPEN` at the time of this call
try {
  ws.send(
    message
  );
} catch (e) {
  bufferedMessages.push(message);
}

but I don't think this would call bufferedMessages.push(message) if the client disconnects while ws.send(message) is executing.

Upvotes: 1

Views: 1271

Answers (1)

Josh Wulf
Josh Wulf

Reputation: 4877

Easy, have the client echo back the messages that it got, all the time.

Or have it resend the last message that it got, on reconnect, and keep a sliding window buffer on the server.

Or a combo. Tag each message with a UUID, and have the client ack them by UUID and flush them from the server buffer on ack. That gives you a pretty solid sliding window that matches what you know has been delivered.

The first Google hit for "WebSockets reliable" has this to say:

But, WebSocket is unreliable, you don’t know anything if the clients missed some messages because the connection was broken in a while. How about if the messages are critical for your clients.

The 8 Fallacies of Distributed Computing #1: "The network is reliable".

Upvotes: 2

Related Questions