Reputation: 3216
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
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