I'm trying to determine if a client has closed a socket connection from netty. Is there a way to do this?
In TCP there is only one way to detect an orderly disconnect, and that is by getting zero as a return value from read()/recv()/recvXXX() when reading. There is also only one reliable way to detect a broken connection: by writing to it.
Description. Once a TCP connection has been established, that connection is defined to be valid until one side closes it. Once the connection has entered the connected state, it will remain connected indefinitely. But in reality the connection will not last indefinitely.
One of Netty's servers is a TCP server. To create a Netty TCP server you must: Create an EventLoopGroup.
The TCP Keepalive Timer feature provides a mechanism to identify dead connections. When a TCP connection on a routing device is idle for too long, the device sends a TCP keepalive packet to the peer with only the Acknowledgment (ACK) flag turned on.
When probed, the network should deliver the keepalive to the media server and the TCP stack on that host should respond with an immediate TCP RST if the remote process is no longer running. However, in the case of an idle socket timeout, the keepalive may be silently discarded by the device or software that dropped the connection.
Send TCP Keepalives successfully (within 15 minutes), before idle socket timeout (typically 60 or 30 minutes). Make sure TCP Keepalives retry at least as robustly as TCP data retransmission to prevent spurious connection drop.
When the TCP stack on the master server eventually detects the lost connection, nbjm will report the job as failed and retry the job. How to detect the dropped connection sooner, so job resources are released and the job is retried more quickly?
If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.」 However, We found that MSDN in this treatment method is often ineffective in practical applications (Sorry about that), can not detect the network has been disconnected.
On a usual case where a client closes the socket via close()
and the TCP closing handshake has been finished successfully, a channelInactive()
(or channelClosed()
in 3) event will be triggered.
However, on an unusual case such as where a client machine goes offline due to power outage or unplugged LAN cable, it can take a lot of time until you discover the connection was actually down. To detect this situation, you have to send some message to the client periodically and expect to receive its response within a certain amount of time. It's like a ping - you should define a periodic ping and pong message in your protocol which practically does nothing but checking the health of the connection.
Alternatively, you can enable SO_KEEPALIVE
, but the keepalive interval of this option is usually OS-dependent and I would not recommend using it.
To help a user implement this sort of behavior relatively easily, Netty provides ReadTimeoutHandler
. Configure your pipeline so that ReadTimeoutHandler
raises an exception when there's no inbound traffic for a certain amount of time, and close the connection on the exception in your exceptionCaught()
handler method. If you are the party who is supposed to send a periodic ping message, use a timer (or IdleStateHandler
) to send it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With