taoensso / sente

Realtime web comms library for Clojure/Script
https://www.taoensso.com/sente
Eclipse Public License 1.0
1.73k stars 193 forks source link

Websocket drops and reconnects every 120s with ClosedChannelException #400

Closed TuggyNE closed 2 years ago

TuggyNE commented 2 years ago

Using both CLJ and CLJS clients, I see an entry like this in the server log every ~120 seconds: ERROR [taoensso.sente:814] - ring-req->server-ch-resp error: java.nio.channels.ClosedChannelException On the CLJ side, I see log entries like this: WARN [taoensso.sente:1174] - Chsk is closed: will try reconnect attempt (1) in 1319 ms

Both client and server are configured to send :chsk/ws-ping at intervals less than 120 seconds, and those are in fact received. I'm using ring-jetty-9a (0.16.1) for websockets, which has two relevant timeouts, both of which should be longer than the observed failure period:

:max-idle-time - the maximum idle time in milliseconds for a connection (default 200000) :ws-max-idle-time - the maximum idle time in milliseconds for a websocket connection (default 500000)

Any suggestions to find what's causing the unexpected channel closing?

ptaoussanis commented 2 years ago

@TuggyNE Hi there!

I'd suggest starting with the reference example project. Try confirm that that's working on your system, then swap in your web server, etc. That should help you identify the cause of your trouble.

Hope that's of some help!

TuggyNE commented 2 years ago

Well, I'm still not sure how the timeout was caused, but while testing Ring middleware, config, etc to see which ones were necessary to trigger the problem, I discovered :csrf-token-fn nil in the server's Sente config. I don't know why that was set, but fixing it partially helped: CLJS now stays connected. CLJ still does not.

TuggyNE commented 2 years ago

Looks like it's a feature of the Java WS library Sente uses. (-> ws-client-conn :chsk :socket_ deref (.setConnectionLostTimeout 0) is a hacky workaround that eliminates the problem for me. I don't know why Sente doesn't send WS pongs, but maybe it seemed redundant given the higher-level protocol support for something equivalent. So either sending pongs or disabling the connection-lost timeout would be a good idea for this.