Netty中ChannelHandler的生命週期

在使用Netty進行網絡編程的時候,一般須要在網絡鏈接的不一樣階段進行相應的操做,好比在鏈接創建時,客戶端向服務端發起認證,在接收到數據時對數據內容進行解析等等。那麼,鏈接的不一樣階段在netty中如何表示呢? 這即是本文討論的內容,Netty中ChannelHandller的生命週期。java

首先咱們先分析小網絡鏈接的生命週期,鏈接創建 ---> 數據交互 ---> 鏈接斷開,在數據交互階段,包括從鏈接中讀取數據和向鏈接中寫入數據。知道了鏈接的生命週期,就能夠按圖索驥的在各個階段進行想要的操做。而在Netty中,網絡鏈接的不一樣生命週期均可以經過回調的方式來綁定相應的邏輯,這個回調接口就是ChannelHandler,這裏主要咱們以ChannelInboundHandler爲例進行分析。在ChannelInboundHandler中定義了以下和生命週期相關的接口:編程

  • channelRegistered
  • channelUnregistered
  • channelActive
  • channelInactive
  • channelRead
  • channelReadComplete

加上在父類``中定義的兩個:服務器

  • handlerAdded
  • handlerRemoved

這些回調接口的調用書序是什麼呢?咱們經過寫一個LifeCycleHandler來看下ChannelInboundHandler的生命週期的順序。網絡

public class LifeCycleInBoundHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelRegistered: channel註冊到NioEventLoop");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelUnregistered: channel取消和NioEventLoop的綁定");
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelActive: channel準備就緒");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelInactive: channel被關閉");
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) 
            throws Exception {
        out.println("channelRead: channel中有可讀的數據" );
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelReadComplete: channel讀數據完成");
        super.channelReadComplete(ctx);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("handlerAdded: handler被添加到channel的pipeline");
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("handlerRemoved: handler從channel的pipeline中移除");
        super.handlerRemoved(ctx);
    }
}

啓動服務器和Client,鏈接成功後,斷開client的鏈接,Server端輸出結果以下:ide

handlerAdded: handler被添加到channel的pipeline
channelRegistered: channel註冊到NioEventLoop
channelActive: channel準備就緒
channelRead: channel中有可讀的數據
channelReadComplete: channel讀數據完成
channelReadComplete: channel讀數據完成
channelInactive: channel被關閉
channelUnregistered: channel取消和NioEventLoop的綁定
handlerRemoved: handler從channel的pipeline中移除

從上面結果能夠知道,從鏈接創建到鏈接斷開,handler的生命週期回調接口調用順序以下:oop

handlerAdded -> channelRegistered 
-> channelActive -> channelRead -> channelReadComplete
-> channelInactive -> channelUnRegistered -> handlerRemoved

下面具體說下每一個回調的具體含義:線程

  1. handlerAdded: 新創建的鏈接會按照初始化策略,把handler添加到該channel的pipeline裏面,也就是channel.pipeline.addLast(new LifeCycleInBoundHandler)執行完成後的回調;
  2. channelRegistered: 當該鏈接分配到具體的worker線程後,該回調會被調用。
  3. channelActive:channel的準備工做已經完成,全部的pipeline添加完成,並分配到具體的線上上,說明該channel準備就緒,能夠使用了。
  4. channelRead:客戶端向服務端發來數據,每次都會回調此方法,表示有數據可讀;
  5. channelReadComplete:服務端每次讀完一次完整的數據以後,回調該方法,表示數據讀取完畢;
  6. channelInactive:當鏈接斷開時,該回調會被調用,說明這時候底層的TCP鏈接已經被斷開了。
  7. channelUnREgistered: 對應channelRegistered,當鏈接關閉後,釋放綁定的workder線程;
  8. handlerRemoved: 對應handlerAdded,將handler從該channel的pipeline移除後的回調方法。
相關文章
相關標籤/搜索