【Netty】心跳机制

Netty心跳机制

服务器要知道每个Socket是否活跃;要不断监听每个Channel处于什么状态;

实现:

  • 服务器超过3s没有读,提示读空闲;
  • 服务器超过5s没有写,提示写空闲;
  • 超过7s没有读写,提示读写空闲;
  1. 配置ServerBootstrap:

    serverBootstrap.group(bossGroup, workerGroup)
    // boss关联日志服务器
    .handler(new LoggingHandler(LogLevel.INFO)) 
    // worke添加Handler,初始化Channel
    .childHandler(new ChannelInitializer<SocketChannel>() {
    	@Override
    	protected void initChannel(SocketChannel ch) throws Exception {
    		ChannelPipeline pipeline = ch.pipeline();
    		// 添加检测空闲状态的Handler
            pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS));
    });
    
  2. IdleStateHandler:添加此Handler即开启心跳机制;

    IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit)
    

    三个主要参数:

    • readerIdleTime:多久Server没有读取Client数据;
    • writerIdleTime:多久Server没有发送给Client数据
    • allIdleTime:多久Server既没有读,也没有写数据给Client;

    上述的三种事件,在满足一定条件后,会触发userEventTriggered(自定义Handler重写的方法)方法,做出相应的处理;

  3. 实现userEventTriggered

    这三种事件:(READER_IDLE,WRITER_IDLE,ALL_IDLE)在IdleState枚举类下

    public enum IdleState {
        READER_IDLE,
        WRITER_IDLE,
        ALL_IDLE
    }
    

    通过switch语句判断事件类型,做出相应的动作:

    public class ServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    		if (evt instanceof 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 = "读写空闲";
                        // 如果发生读写空闲,将通道关闭
                        ctx.channel().close();
                        break;
                }
                SocketAddress socketAddress = ctx.channel().remoteAddress();
                System.out.println("[" + socketAddress + "] 触发:" + eventType);
            }
        }
    }
    

posted @ 2020-04-02 08:04  mussessein  阅读(172)  评论(0编辑  收藏  举报