netty版本
- netty版本:
io.netty:netty-all:4.1.33.Final
心跳检测
-
心跳:即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保TCP连接的有效性。
-
为什么需要心跳?
- 因为网络的不可靠性, 有可能在TCP保持长连接的过程中, 由于某些突发情况, 例如
网线被拔出
,突然掉电
等, 会造成服务器和客户端的连接中断。在这些突发情况下, 如果恰好服务器和客户端之间没有交互的话, 那么它们是不能在短时间内发现对方已经掉线的。为了解决这个问题, 我们就需要引入心跳
机制。
- 因为网络的不可靠性, 有可能在TCP保持长连接的过程中, 由于某些突发情况, 例如
-
心跳机制的工作原理是: 在服务器和客户端之间一定时间内没有数据交互时, 即处于 idle(空闲)状态时, 客户端或服务器会发送一个特殊的数据包(一般都是自定义)给对方, 当接收方收到这个数据报文后, 也立即发送一个特殊的数据包回应发送方, 即一个
PING-PONG
交互。自然地, 当某一端收到心跳消息后, 就知道了对方仍然在线, 这就确保TCP连接的有效性。一般情况下,心跳检测到连接失效后,还需要配合重连来进行进一步的重新连接。 -
心跳机制
- 使用TCP协议层的keepalive机制
- 应用层自定义心跳机制,这里主要讲应用层实现
-
在Netty中, 实现心跳机制的关键是
IdleStateHandler
,IdleStateHandler
所产生的IdleStateEvent
的处理逻辑。在userEventTriggered
中, 根据IdleStateEvent
的state()
的不同, 而进行不同的处理。/** * 心跳既可以从客户端发起也可以从服务端发起,此处从客户端发起 */ public class HeartbeatClient extends AbstractClient { // 读超时 private static final int READ_IDEL_TIME_OUT = 4; // 写超时 private static final int WRITE_IDEL_TIME_OUT = 5; // 所有超时 private static final int ALL_IDEL_TIME_OUT = 7; public HeartbeatClient(String host, int port) { super(host, port); } @Override public ChannelHandler[] getChannelHandlers() { return new ChannelHandler[]{ new IdleStateHandler(READ_IDEL_TIME_OUT, WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS), new HeartbeatClientHandler() }