• Netty 应用:心跳检测


    心跳检测应用场景:在集群内节点与节点之间互相感知彼此是否存活。

    • 为什么需要心跳检测?netty不是提供断开连接的回调方法么?

    在app的应用场景中,手机如果开飞行模式或者强制关机,服务端是感知不到tcp长连接已经关闭的,这时候就需要服务端向客户端发送心跳包来检测连接是否已经断开。

    netty除了提供了各种编解码器,还提供了各种处理器handler,比如空闲状态IdleStateHandler

     

    服务端实现

    /**
     * Created by fubin on 2019/7/13.
     */
    public class BeartBeatServer {
        public static void main(String[] args) {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try{
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(bossGroup,workerGroup)
                        .channel(NioServerSocketChannel.class)
                        //增加日志handler
                        .handler(new LoggingHandler(LogLevel.INFO))
                        .childHandler(new HeartBeatInitializer());
    
                ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }
    class  HeartBeatInitializer extends ChannelInitializer<SocketChannel> {
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            ChannelPipeline channelPipeline = socketChannel.pipeline();
            //netty还提供了各种各样的处理器,比如空闲检测的handler
            channelPipeline.addLast(new IdleStateHandler(5,7,10, TimeUnit.SECONDS));
            channelPipeline.addLast(new HeartBeatHandler());
        }
    }
    class HeartBeatHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            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;
            }
            System.out.println(ctx.channel().remoteAddress() + "超时事件:" + eventType);
            ctx.channel().close();
        }
    }

    客户端实现

    client代码可以使用 上一篇netty socket服务的聊天程序的client

    Netty心跳检测核心Handler IdleStateHandler 的API解释

    当一个Channel没有执行读,写或者两者都没执行时,会触发一个IdleStateEvent事件。
    支持的空闲idle状态

    属性含义
    readerIdleTime 一个IdleStateEvent的状态为IdleState.READER_IDLE事件将在指定期间不执行读取操作时触发,指定0禁用
    writerIdleTime 一个IdleStateEvent的状态为IdleState.WRITE_IDLE事件将在指定期间不执行写操作时触发,指定0禁用
    allIdleTime 一个IdleStateEvent的状态为IdleState.ALL_IDLE事件将在指定期间读写操作都不执行时触发,指定0禁用
    //在30秒没有出栈流量时发送ping消息的示例
    //当60秒没有入栈流量时连接关闭
    class MyChannelInitializer extends ChannelInitializer<Channel>{
        @Override
        protected void initChannel(Channel ch) {
            ch.pipeline().addLast("idleStateHandler",new IdleStateHandler(60,30,0));
            ch.pipeline().addLast("myHandler",null);
        }
    }
    class MyHandler extends ChannelDuplexHandler{
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            if(evt instanceof IdleStateEvent){
                IdleStateEvent e = (IdleStateEvent)evt;
                if(e.state() == IdleState.READER_IDLE){
                    ctx.close();
                }else if(e.state() == IdleState.WRITER_IDLE){
                    ctx.writeAndFlush("写空闲!");
                }
            }
        }
    }
    
    //server main
    ServerBootstrap bootstrap = ...;
    bootstrap.childHandler(new MyChannelInitializer());
  • 相关阅读:
    Fitness
    【代码优化】Unity查漏补缺
    Fitness
    MonoBehaviour生命周期与对象数据池应用
    Fitness
    点、向量、方向在局部与世界坐标系转换的对比
    在企业运营中的感触
    技术杂想2015年夏天
    Heimich manoeuvre 海姆利克氏操作
    徒手CPR心脏复苏
  • 原文地址:https://www.cnblogs.com/fubinhnust/p/11940636.html
走看看 - 开发者的网上家园