使用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);
        }
    }

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