socketio / socket.io

Realtime application framework (Node.JS server)
https://socket.io
MIT License
60.9k stars 10.09k forks source link

Connection State Recovery on "Transport Close Undefined" #4652

Closed mikehudson2 closed 1 year ago

mikehudson2 commented 1 year ago

We're using connectionStateRecovery to 'recycle' disconnected socket.id's. Our intention is that where a socket is disconnected, a new socket will be created with the same socketId as the disconnected socket. This works where the disconnect reason/description is "ping timeout". However, for disconnections described as "transport close undefined" a new socket (with a new socketId) is created - the original socketId is lost.

Is there a difference in behaviour between these two type of disconnection by design and if so why? Is there another way to 'recycle' the socketId of a socket disconnected due to "transport close undefined"?

Our sockets are set up as: pingInterval: 3000, pingTimeout: 3000 connectionStateRecovery: { maxDisconnectionDuration: 10000, skipMiddlewares: false, }

Socket.IO server version: 4.6 running on Github Codespaces Node.js

darrachequesne commented 1 year ago

Hi! transport close errors should be recoverable too:

https://github.com/socketio/socket.io/blob/7952312911e439f1e794760b50054565ece72845/lib/socket.ts#L49-L56

The socket ID is not persisted when the user reloads its browser tab though, which might explain why the session is not recovered after a transport close error.

mikehudson2 commented 1 year ago

Thanks Darra. We see 'transport close' when a client tab is closed (expected) but also spontaneously (not expected and a problem). With the server running on node.js within Github Codespaces (i.e. observing the server terminal from within a browser) and with even only one client connected (1 browser tab), we always see a transport close disconnection, typically after 3 to 4.5 minutes.

Out of curiosity, how is the server aware that a 'transport close disconnection is due to a browser tab closure rather than a 'recoverable' reason?

darrachequesne commented 1 year ago

we always see a transport close disconnection, typically after 3 to 4.5 minutes.

It seems like there is something that closes the WebSocket connection after a given delay, not sure whether this delay is configurable within Github Codespaces. But that shouldn't be a problem though, if the session is properly recovered upon reconnection.

Out of curiosity, how is the server aware that a 'transport close disconnection is due to a browser tab closure rather than a 'recoverable' reason?

In both cases, the server is notified that the WebSocket connection gets closed (hence the transport close reason), so it will store the session. Upon reconnection, the client sends its previous session ID and the server tries to restore it.

Reference: https://socket.io/docs/v4/connection-state-recovery#how-it-works-under-the-hood

darrachequesne commented 1 year ago

Closed due to inactivity, please reopen if needed.