yjs / y-websocket

Websocket Connector for Yjs
https://docs.yjs.dev/ecosystem/connection-provider/y-websocket
MIT License
497 stars 256 forks source link

Call onclose when closing the connection in the checkinterval #93

Open johnstleger opened 2 years ago

johnstleger commented 2 years ago

Context In Safari the Websocket does not call onclose when the socket is closed manually.

The problem This means that if a connection is closed in the interval in Safari it doesn't try to reconnect. Users end up in a state where y-websocket states that they are connected. But they are disconnected and y-websocket doesn't try to reconnect... users lose their edits.

Reproduce It's easy to reproduce. Switch from one wifi network to another (i.e. to your phone using tethering) and you'll see it disconnects silently and never reconnects.

dmonad commented 2 years ago

I'm a bit confused. Does this happen when you manually close the connection (provider.disconnect()) or when switching between routers?

If I can't detect that a connection is closed, then this is probably a browser issue.

TJackwood-Jasper commented 2 years ago

@dmonad I'm seeing a similar issue now using Chrome as well.

I think the issue arises from the default WebSocket logic not "fully closing" for some reason; if I set up my y-websocket connection, then disconnect my connection between client and server, the client will eventually trigger the ws.close() here, but the websocket status sits forever in a CLOSING status and never actually transitions to a CLOSED state which would actually trigger the .onclose(...) logic.

Looks like the ws lib has struggled with this historically, but they have a timer running to forcibly close the connection fully if the other peer fails for a weird reason: https://github.com/websockets/ws/issues/1125. Do you maybe need something similar here to prevent this CLOSING state limbo?

Edit: I reproduced this using Chrome devtools to set my client-side network throttling to "Offline" under the "Network" tab