什么是心跳检测机制?
心跳检测机制就是服务端会定时向客户端发送一个心跳检测包,或者客户端向服务端发送,以确保连接的有效性机制。
Netty提供了IdleStateHandler来进行心跳检测
IdleStateHandler
IdleStateHandler是Netty提供的空闲状态处理器
参数说明:
- readerIdleTime:读的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
- writerIdleTime:写的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
- allIdleTime:读写的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
- unit:空闲时间单位,默认为秒(TimeUnit.SECONDS)
将IdleStateHandler加入到pipeline管道中,当满足设定的超时时间后,IdleStateHandler会自动触发IdleStateEvent,会传递给管道中的下一个handler中的userEventTriggered事件去处理
代码示例:
public class HeartBeatServer {
public static void main(String[] args) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 获取管道
ChannelPipeline pipeline = socketChannel.pipeline();
/**
* IdleStateHandler:Netty提供的空闲状态处理器
* 参数说明:
* readerIdleTime:读的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
* writerIdleTime:写的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
* allIdleTime:读写的空闲时间,超出此时间就会发送一个心跳检测包,检测是否连接
* unit:空闲时间单位,默认为秒(TimeUnit.SECONDS)
*
* 当满足上述其中一个条件后,就会自动触发IdleStateEvent,会传递给管道中的下一个handler中的userEventTriggered事件去处理
*/
pipeline.addLast(new IdleStateHandler(5,10,15, TimeUnit.SECONDS));
// 加入自定义handler
pipeline.addLast(new HeartBeatServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class HeartBeatServerHandler extends ChannelInboundHandlerAdapter {
/**
* 心跳检测事件处理
*
* @param ctx
* @param evt
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
String eventType = null;
switch (idleStateEvent.state()) {
case READER_IDLE: // 读空闲
eventType = "读空闲";
break;
case WRITER_IDLE: // 写空闲
eventType = "写空闲";
break;
case ALL_IDLE: // 读写空闲
eventType = "读写空闲";
break;
default:
break;
}
System.out.println("超时事件类型:" + eventType);
}
}
}