IdleStateHandler
IdleStateHandler
处理空闲状态的handler
;
new IdleStateHandler(3,5,7, TimeUnit.SECONDS)
//long readerIdleTime:表示多长时间没读,就会发送一个心跳检测包检测是否连接
//long writerIdleTime:表示多长时间没写,就会发送一个心跳检测包检测是否连接
// long allIdleTime:表示多长时间没写没读,就会发送一个心跳检测包检测是否连接
// TimeUnit unit
//当IdleStateEvent触发后,就会触发给管道的下一个handler去处理
//通过回调下一个handler的userEventTiggered去处理
//IdleStateEvent可能是读空闲,写空闲或读写空闲
实例要求:
- 编写一个 Netty心跳检测机制案例, 当服务器超过3秒没有读时,就提示读空闲
- 当服务器超过5秒没有写操作时,就提示写空闲
- 实现当服务器超过7秒没有读或者写操作时,就提示读写空闲
服务端:
核心代码:
new ChannelInitializer<SocketChannel>() {
//给管道设置处理器
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//IdleStateHandler处理空闲状态的handler
//long readerIdleTime:表示多长时间没读,就会发送一个心跳检测包检测是否连接
//long writerIdleTime:表示多长时间没写,就会发送一个心跳检测包检测是否连接
// long allIdleTime:表示多长时间没写没读,就会发送一个心跳检测包检测是否连接
// TimeUnit unit
//当IdleStateEvent触发后,就会触发给管道的下一个handler去处理
//通过回调下一个handler的userEventTiggered去处理
//IdleStateEvent可能是读空闲,写空闲或读写空闲
pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));
//加入一个对空闲检测进一步处理的自定义的handler
pipeline.addLast(new MyServerHandler());
}
});
完整代码
public class MyServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(3);
try {
//2.创建服务器端的启动对象,配置参数
ServerBootstrap serverBootstrap = new ServerBootstrap();
//3.使用链式编程进行设置
serverBootstrap
//设置两个线程组
.group(bossGroup, workerGroup)
//使用NioServerSocketChannel作为服务器的通道实现
.channel(NioServerSocketChannel.class)
//改handler对应的是bossGroup
.handler(new LoggingHandler(LogLevel.INFO))
//给我们的workerGroup的EventLoopGroup对应的管道设置处理器Handler
.childHandler(
//创建一个通道测试对象(匿名对象)
new ChannelInitializer<SocketChannel>() {
//给管道设置处理器
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//IdleStateHandler处理空闲状态的handler
//long readerIdleTime:表示多长时间没读,就会发送一个心跳检测包检测是否连接
//long writerIdleTime:表示多长时间没写,就会发送一个心跳检测包检测是否连接
// long allIdleTime:表示多长时间没写没读,就会发送一个心跳检测包检测是否连接
// TimeUnit unit
//当IdleStateEvent触发后,就会触发给管道的下一个handler去处理
//通过回调下一个handler的userEventTiggered去处理
//IdleStateEvent可能是读空闲,写空闲或读写空闲
pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));
//加入一个对空闲检测进一步处理的自定义的handler
pipeline.addLast(new MyServerHandler());
}
});
//启动服务器
ChannelFuture sync = serverBootstrap.bind(8005).sync();
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
服务端handler:
public class MyServerHandler extends ChannelInboundHandlerAdapter {
//ctx上下文
//evt 事件
//出现超时,连接并没有断
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent){
//将event向下转型IdleStateEvent
IdleStateEvent event=(IdleStateEvent)evt;
String eventType=null;
switch (event.state()){
case READER_IDLE:
eventType="读空闲";
break;
case WRITER_IDLE:
eventType="写空闲";
break;
case ALL_IDLE:
eventType="读写空闲";
break;
default:
eventType=null;
break;
}
System.out.println(ctx.channel().remoteAddress()+"--超时时间--"+eventType);
System.out.println("服务器做相应的处理...");
//如果发生空闲了,关闭通道
// ctx.channel().close();
}
}
}
客户端连接8005端口。
启动服务和客户端,啥也不干
把客户端强行关了