Netty提供了对心跳机制的天然支持,心跳可以检测远程端是否存活,或者活跃.
IdleStateHandler
构造函数:
1 | public IdleStateHandler( |
- readerIdleTime: 读超时时间,即该时间内自己未收到对方发送的消息
- writerIdleTime:写超时时间,即自己在该时间内没向对方发送消息
- allIdleTime:读写超时时间
- unit:时间单位
Note:
- 第一个构造函数调用第二个构造函数,时间单位默认为秒。
- 超时时间设置为0,表示disable,即不设置该项。
- 一般是在通信双方没有业务消息交互后,然后又超过了设置的超时时间,则需要以发送心跳信息来保持长连接,另外也能检测对方是否宕机。
Server端
一般在ChannelPipeline第一个加入以下:
1 | pipeline.addLast(new IdleStateHandler(5, 0, 0)); |
第一个参数为5,表示在服务器端会每隔5秒来检查一下ChannelHandler的channelRead()方法被调用的情况,即是否收到客户端的消息,如果在5秒内该通道链上的所有ChannelHandler的channelRead()方法都没有被触发,就会触发调用ChannelHandler的userEventTriggered()方法。
我们可以写一个ChannelHandler,重写其userEventTriggered()方法,判断如果两次没接到心跳消息,就主动断开与客户端的连接。
Client端
一般在ChannelPipeline第一个加入以下:
1 | pipeline.addLast(new IdleStateHandler(0, 4, 0)); |
第二个参数为4,表示客户端每隔4秒会检查一下ChannelHandler的write()方法被调用情况,即客户端4秒内是否向服务端发送过消息,如果在4秒内该通道链上的所有ChannelHandler的write()都没有被调用,就会触发调用ChannelHandler的userEventTriggered()方法。
我们可以写一个ChannelHandler,重写其userEventTriggered()方法,当客户端发送完业务消息后,空闲时间超过4秒,则该方法会被调用,我们可在这个方法内做向服务端发送心跳消息的逻辑,用来保持和服务端的长连接。
总结
简而言之:IdleStateHandler这个类会根据你设置的超时参数的类型和值,循环去检测channelRead和write方法多久没有被调用了,如果这个时间超过了你设置的值,那么就会触发对应的事件,read触发read,write触发write,all触发all
- 如果超时了,则会调用userEventTriggered方法,且会告诉你超时的类型
- 如果没有超时,则会循环定时检测,除非你将IdleStateHandler移除Pipeline