Netty+SpringBoot+FastDFS+Html5實現聊天App(六)

Netty+SpringBoot+FastDFS+Html5實現聊天App,項目介紹
java

Netty+SpringBoot+FastDFS+Html5實現聊天App,項目github連接
git

本章完整代碼連接

github

本章將給聊天App_PigChat加上心跳機制。segmentfault



爲何要實現心跳機制

若是沒有特地的設置某些選項或者實現應用層心跳包,TCP空閒的時候是不會發送任何數據包。也就是說,當一個TCP的socket,客戶端與服務端誰也不發送數據,會一直保持着鏈接。這其中若是有一方異常掉線(例如死機、路由被破壞、防火牆切斷鏈接等),另外一端若是沒有發送數據,永遠也不可能知道。這對於一些服務型的程序來講,是災難性的後果,將會致使服務端socket資源耗盡socket

舉個簡單的例子,當咱們由於特殊狀況打開飛行模式 ,在處理完事件以後再關閉飛行模式,這時候若是再進入應用程序中,咱們將以新的channel進入,可是以前的channel仍是會保留。ide

所以,爲了保證鏈接的有效性、及時有效地檢測到一方的非正常斷開,保證鏈接的資源被有效的利用,咱們就會須要一種保活的機制,一般改機制兩種處理方式:netty

一、利用TCP協議層實現的Keepalive;code

二、本身在應用層實現心跳包。繼承



實現心跳機制

新建一個HeartBeatHandler用於檢測channel的心跳。事件

繼承ChannelInboundHandlerAdapter,並重寫其userEventTriggered方法。當客戶端的全部ChannelHandler中4s內沒有write事件,則會觸發userEventTriggered方法。

首先咱們判斷evt是不是IdleStateEvent的實例,IdleStateEvent用於觸發用戶事件,包含讀空閒/寫空閒/讀寫空閒。

對evt進行強制履行轉換後,經過state判斷其狀態,只有當其該channel處於讀寫空閒的時候纔將這個channel關閉。

/**
 * @Description: 用於檢測channel的心跳handler 
 *                  繼承ChannelInboundHandlerAdapter,從而不須要實現channelRead0方法
 */
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        
        // 判斷evt是不是IdleStateEvent(用於觸發用戶事件,包含 讀空閒/寫空閒/讀寫空閒 )
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent)evt;        // 強制類型轉換
            
            if (event.state() == IdleState.READER_IDLE) {
                System.out.println("進入讀空閒...");
            } else if (event.state() == IdleState.WRITER_IDLE) {
                System.out.println("進入寫空閒...");
            } else if (event.state() == IdleState.ALL_IDLE) {
                
                System.out.println("channel關閉前,users的數量爲:" + ChatHandler.users.size());
                
                Channel channel = ctx.channel();
                // 關閉無用的channel,以防資源浪費
                channel.close();
                
                System.out.println("channel關閉後,users的數量爲:" + ChatHandler.users.size());
            }
        }
        
    }
    
}



增長心跳支持

在原來的WSServerInitialzer中增長心跳機制的支持。

// ====================== 增長心跳支持 start    ======================
        // 針對客戶端,若是在1分鐘時沒有向服務端發送讀寫心跳(ALL),則主動斷開
        // 若是是讀空閒或者寫空閒,不處理
        pipeline.addLast(new IdleStateHandler(8, 10, 12));
        // 自定義的空閒狀態檢測
        pipeline.addLast(new HeartBeatHandler());
        // ====================== 增長心跳支持 end    ======================
相關文章
相關標籤/搜索