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端口。

启动服务和客户端,啥也不干

openresty 心跳 netty心跳检测_服务器


把客户端强行关了

openresty 心跳 netty心跳检测_ide_02