I see you have a 1 hour idle timeout at the server side.
That's nice and all, but if you have clients connecting over mobile networks you'll have to contend with intermediaries with their own TCP idle timeouts. (quite common)
I've seen mobile networks close idle TCP connections due to idle timeout.
I've seen SIM cards with configurations to close idle TCP connections that last too long.
I've seen specific mobile towers close idle TCP connections that last too long.
I've seen overloaded mobile networks close idle TCP connections.
If the mobile network idle times out, and you don't send any traffic on that connection from the server side, you won't know about it until the server idle timeout triggers.
You'll want to make sure your program is aware of client reconnects and whatnot, usually you see that as a result of a mobile device.
It can even happen with a mobile device moves from network to network.
I would recommend not relying on the 1 hour idle timeout to cleanup your dead connections.
Instead, use the websocket protocol's ping/pong after a period of time to ensure the other side is still there.
I would use ping/pong frequency faster than 5 minutes. (no more than 5 minutes between ping send).
Why 5 minutes? Well, that's the most common mobile network TCP idle timeout I've personally encountered (its even a common idle timeout seen on the cloud providers own load balancers: google, aws, azure, etc. which on some providers you cannot increase, only decrease).