WebSocket connection closing prematurely


I’m using gun 2.0 to create a WebSocket connection to a webserver implemented with cowboy 2.10.0. I noticed that even if there’s a constant stream of data going through from the client to the server (multiple messages per second), but no explicit ping is sent, my client logs that the WebSocket connection goes down every 60 seconds (I think that’s the default value of the idle_timeout on the cowboy side). I tried to debug what happens and on the client side it looks like the server closes the connection (the gun receives an {gun_down, Conn, ws, {error, closed}, _Refs} Erlang message), but on the server side it looks like the client closes the connection (the cowboy_websocket:websocket_close function is called with the third parameter being {remote,1001,<<>>}). I also noticed that there seem to be more than one cowboy process handling the WebSocket connection even though there is a single WebSocket connection. At least the trace shows multiple processes calling the cowboy_websocket:loop function which looks to be the main loop. This confused me - what does cowboy do here?

Then I modified my client code to send a WebSocket ping every 30 seconds by calling gun:ws_send(Conn, Ref, ping) and suddenly the connection stopped going down. Which is great for things working, but confuses me even more.

Should the WebSocket connection stay alive if only binary frames are sent, but no ping frames?

I don’t know, but you may ask in Slack. The maintainer of cowboy and gun is active there (not here on the Forum), goes by the name of essen.

Cowboy does not send ping frames automatically. You have to implement that in your handler. See also " Keeping the connection alive" chapter in: Nine Nines: Websocket handlers