且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

TCP保持活动状态以确定客户端是否断开网络连接

更新时间:2022-10-15 14:23:02

在通常情况下,客户端通过close()关闭套接字并且TCP关闭握手已成功完成,请使用channelInactive()(或channelClosed() 3)事件将被触发.

但是,在不寻常的情况下(例如,由于断电或LAN电缆未插入而使客户端计算机脱机),可能要花费大量时间,直到您发现连接实际上已断开.要检测到这种情况,您必须定期向客户端发送一些消息,并希望在一定时间内接收到它的响应.就像是ping一样-您应该在协议中定义一个定期的ping和pong消息,该消息实际上只是检查连接的运行状况.

或者,您可以启用SO_KEEPALIVE,但是此选项的keepalive间隔通常取决于操作系统,我不建议您使用它.

为帮助用户相对轻松地实现这种行为,Netty提供了ReadTimeoutHandler.配置管道,以使ReadTimeoutHandler在一定时间内没有入站流量时引发异常,并在exceptionCaught()处理程序方法中关闭该异常的连接.如果您是应该发送定期ping消息的一方,请使用计时器(或IdleStateHandler)进行发送.

I'm trying to determine if a client has closed a socket connection from netty. Is there a way to do this?

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.