0x02. 协议 PONG
在 setUpHandlers 函数中有一行逻辑。目的是当 tcp链接 没有读写 IDLE_TIME_SECONDS 秒时产生一次 IdleStateEvent 事件。 事件会调用 ctx.fireUserEventTriggered(evt); 最终转发到 Client.userEventTriggered() 中。
pipeline.addLast(“IdleStateHandler”, new IdleStateHandler(0, 0, IDLE_TIME_SECONDS));
当客户端收到 userEventTriggered 时调用 checkIfIdle 函数。
- 记录当前时间 final long pingedAt = System.currentTimeMillis();
- 主动向当前客户端发送一个 SendOpcode.PING 协议 sendPacket(PacketCreator.getPing());
- 注册一个 15秒 定时器管理,TimerManager
- 等待当前客户端收到 SendOpcode.PING 协议后主动发送一个 PONG 协议。
- 如果客户端主动发送 PONG, Client.channelRead 收到数据包, 找到 handler 转到 PONG.KeepAliveHandler 函数。
- KeepAliveHandler 内部调用 Clinet.pongReceived()。记录当时间到 Clinet.lastPong 变量中。
- 回到 checkIfIdle.TimerManager 中。当 15 秒后触发检查 lastPong 小于 pingedAt。那就表示客户端没有回复 PONG 数据包给服务端。表明客户端出现异常情况,直接调用 closeMapleSession 断开tcp网络
PONG 总结
一个基本的心跳。当框架Netty检查当前TCP连接超过30秒没有和服务端通信过,则触发回调主动发送一个 SendOpcode.PING 协议给客户端,并且监控当前客户端15秒内是否有回复过 PONG 协议。如果没有则表明客户端出现异常则主动断开和当前socket的TCP连接。