The session keeps alive after the client has shut down

Feb 23, 2012 at 6:37 PM

In my example, the server connects to a few thousand clients using the MS websocket client assembly. There are two issues:

(1) When these a few thousands clients tried to connect to the single SuperWebSocket server, some connection requests would fail. They were successful later after those failed clients re-tried to connect. Are there some parameters that I shall set to increase the capability of concurrent connect requests, other than the max connection, which I set to a very large int? Were the failure caused by too many concurrent connection requests? How many connections can a SuperWebSocket server support?

(2) After those a few thousands clients shut down (closing the program either gracefully or killed), the SuperWebSocket server kept many sessions (about 50%) of them live. I put some code to check the SocketSession.Status and they were still SessionStatus.Healthy even though the clients were gone hours ago. This seems to be a bug. How do I reliably check the connection's status on the server side? Again, did I mis-configure any parameters? Is there a websocket ping/pong method?

Feb 24, 2012 at 1:37 AM
Edited Feb 24, 2012 at 1:42 AM

1) There is a maxConnectionNumber configuration whose default value is 1000, you can adjust it according your requirement.

2) Really? I have NUnit test cases for websocket closing, and they are running correctly. When client close the connection, it means the client sent the closing handshake to server side, if the server side received the closing handshake, it would send a closing handshake reponse to client side, and then after client receive the resposne, it will close the connection finally. It is the websocket closing procedure which was defined in rfc6455.

Feb 24, 2012 at 3:08 AM

What I meant was when the client process (using the MS websocket library) was shut down or killed, the superwebsocket server was still running. The server shall detect the websocket being closed by the client and close the socket. This worked when there were hundreds of connections, but not a few thousands.

I did call the SocketServerManager.Stop() to clean up the server when the server shuts down, but this is irrelevant to the problem.

I think your unit testing only tested one or a few connections. The problem happened when my client made 3000 concurrent connections to a server. The SessionStatus.Healthy was still healthy after the client process shuts down (double checked in the task manager).

Feb 24, 2012 at 3:12 AM

How the client shutdown the connection?

If the connection was closed properly, the server would know immediately, but if the connection was dropped by accidents like network unplugged or power off, the server would know the connection was dropped in a latency which depends on the tcp keep alive setting.

It is limited by TCP. 

Feb 24, 2012 at 3:34 AM

What you suspect is right. The client attempted to shut down gracefully, but did not disconnect all websockets appropriately, because the client cannot afford to wait for the long time to close all sockets. That's why I asked if there is a ping/pong type of check that we can use to verify the connection on the server side. The MS .Net socket, on the other hand, can detect such a dead socket after some period of time though, I think. There were some parameters set on the .Net socket for the linger state. Sometimes it does not always work, if I remember, especially when the other side of the socket is not .Net.

So, can I implement some keepalive heart beat to validate the connection on the server side, or is there a better option? The client shut down might not always happen due to the nature of many systems, for example, user can simply kill the client app.

Feb 24, 2012 at 3:39 AM

Yes, you can design a application level keep alive, and SuperWebSocket support clearing idle sessions in a interval:

clearIdleSession: true or false, whether clear idle sessions. Default value is false.
clearIdleSessionInterval: the clearing timeout idle session interval. Default value is 120, in seconds.
idleSessionTimeOut: The session timeout period. Default value is 300, in seconds.

BTW, websocket(rfc6455) defined PING/PONG, and WebSocket4Net implemented sending PING to server in a interval.

Feb 24, 2012 at 4:58 AM

I forgot one thing. I planed a feature that create a closing handshake queue, if a session stay in the queue for a long time, it will be killed.

I'll implement it in next release of SuperWebSocket.

Apr 4, 2013 at 7:07 AM
Hi, PONG actualizes LastActiveTime, but is some ability to have separate LastPongTime to implement heartbeat?
Because, if client disconnects (not gracefully), server is still sending messages and LastActiveTime get actualised.