为什么Netty要有读写检测(心跳检测)呢?

按照我们之前项目来看Netty内部本身就有一个handlerRemoved方法

netty server 连接被remove后 断线重连 netty 断开连接_Netty读写检测(心跳检测)与长连接

而且我们之前的时候也完全可以检测到,当客服端退出应用程序之后,handlerRemoved就会被执行,移除掉相应的channel ,但是实际中远远没有这么简单。

例如:当手机客服端与服务端建立好长连接之后,但是手机突然开了飞行模式或者直接关机,这种情况下netty是无法检测到该channel已经退出的,所以这个时候我们就需要心跳检测了。

 

创建Myserver,这里的话你得理解handler方法和childHandler的区别,handler方法针对的是bossGroup,childHandler针对的是workerGroup。

netty server 连接被remove后 断线重连 netty 断开连接_Netty读写检测(心跳检测)与长连接_02

 创建管道初始化器MyServerInitializer,这里有一个IdelStateHandler处理器

netty server 连接被remove后 断线重连 netty 断开连接_写数据_03

当一个channel一段时间没有执行读和写操作的时候,就会触发一个空闲状态事件

netty server 连接被remove后 断线重连 netty 断开连接_Netty的深入浅出_04

第一个是读的时间(当在这个时间内没有读操作的话,就执行空闲状态事件),第二个是写的时间(当在这个时间内没有写操作的话,就执行空闲状态事件),第三个是加一起的时间(当在这个时间内没有读或者写操作的话,就执行空闲状态事件)

netty server 连接被remove后 断线重连 netty 断开连接_写数据_05

在MyServer中加入管道初始化器

netty server 连接被remove后 断线重连 netty 断开连接_服务端_06

 准备创建自己的空闲检测处理器

netty server 连接被remove后 断线重连 netty 断开连接_Netty读写检测(心跳检测)与长连接_07

 创建一个MyServerHandler,这里和之前的处理器继承有所不同,之前程序中继承的是SimpleChannelInboundHandler

netty server 连接被remove后 断线重连 netty 断开连接_写数据_08

 ChannelInboundHandlerAdpter源码发现SimpleChannelInboundHandler是它的子类

netty server 连接被remove后 断线重连 netty 断开连接_客户端_09

当该方法被触发之后,就会将当前时间转发给下一个管道channel

netty server 连接被remove后 断线重连 netty 断开连接_Netty的深入浅出_10

 对当前事件(event)的状态进行检测

netty server 连接被remove后 断线重连 netty 断开连接_服务端_11

在控制台中打印出,一直没有状态的客户端,以及关闭该客户端

为什么可以关闭呢:

因为当前channel已经进入了该事件,说明当前channel是其中三种状态之一,所以需要关闭,中间的switch是为了获得状态值进行打印。

netty server 连接被remove后 断线重连 netty 断开连接_服务端_12

 因为客户端是没有任何要更改的,直接使用上一个程序编写的就可以了

启动服务器

启动客户端:

netty server 连接被remove后 断线重连 netty 断开连接_Netty读写检测(心跳检测)与长连接_13

 显示信息:

netty server 连接被remove后 断线重连 netty 断开连接_服务端_14

 

重新启动:

客户端随便写东西

netty server 连接被remove后 断线重连 netty 断开连接_写数据_15

 

服务端:

原因是客户端已经写数据了,服务端就可以监听到客户端在写数据,这时候服务端就一直在读,但是由于没有写数据给客户端所以是写空闲

netty server 连接被remove后 断线重连 netty 断开连接_客户端_16