使用netty实现心跳检查

项目背景:
硬件设备和服务器websocket长连接通讯

使用技术:
java/netty

心跳频率和关闭时长:
看设备接入数和业务要求,比如6秒一个心跳包,对方收到后也返回一个心跳响应。双方2.5个周期内没收到数据则关闭各自链接。常用心跳周期如2s,4s,6s,8s,10s...

哪个来发:
根据我们业务,服务器端来主动发心跳包。开始心跳周期可以设置长点,比如10s。如果业务需求心跳检查要迅速,则修改服务器端的心跳周期,设备固件升级。对于未升级的设备在一个关闭时长内可能会收到2个以上心跳包,不受影响。

代码实现:

READ_IDEL_TIME_OUT=25s
WRITE_IDEL_TIME_OUT=15s
ALL_IDEL_TIME_OUT=10s
HEARTBEAT_REQUEST=“H”
HEARTBEAT_RESPONSE=“B”
 inboundHandler继承的是SimpleChannelInboundHandler<TextWebSocketFrame> 类。


服务器端:
step1.  pipeline初始化配置
pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS));
step2.  在任何一个handler里实现userEventTriggered方法
    @Override  
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)  
            throws Exception {  
        if (evt instanceof IdleStateEvent) {  
            IdleStateEvent event = (IdleStateEvent) evt;  
            if (event.state().equals(IdleState.READER_IDLE)) {  
                //未进行读操作  
                log.error("READER_IDLE");  
                // 超时关闭channel  
                ctx.close();  
            } else if (event.state().equals(IdleState.WRITER_IDLE)) {  
                //log.error("WRITER_IDLE"); 
            } else if (event.state().equals(IdleState.ALL_IDLE)) {  
                //未进行读写  
                log.info("SEND HeartBeat:H"); 
                ctx.channel().writeAndFlush(new TextWebSocketFrame(HEARTBEAT_REQUEST));                
            }  
        }  
    } 

服务器端:
step1.  pipeline初始化配置
pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS));
step2.  在任何一个handler里实现userEventTriggered方法
    @Override  
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)  
            throws Exception {  
        if (evt instanceof IdleStateEvent) {  
            IdleStateEvent event = (IdleStateEvent) evt;  
            if (event.state().equals(IdleState.READER_IDLE)) {  
                //未进行读操作  
                log.error("READER_IDLE");  
                // 超时关闭channel  
                ctx.close();  
            } else if (event.state().equals(IdleState.WRITER_IDLE)) {  
                //log.error("WRITER_IDLE"); 
            } else if (event.state().equals(IdleState.ALL_IDLE)) {  
                //未进行读写             
            }  
        }  
    } 
step3.收到服务器心跳后,响应
    @Override
    protected void channelRead0(ChannelHandlerContext arg0, TextWebSocketFrame arg1) throws Exception {
        // TODO Auto-generated method stub
        String txt=arg1.text();
        log.info("RECV:"+arg1.text());
        if (HEARTBEAT_REQUEST.equals(txt)){
            arg0.channel().writeAndFlush(new TextWebSocketFrame(HEARTBEAT_RESPONSE) ).sync();
            log.info("SEND:"+HEARTBEAT_RESPONSE);
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章