Netty中ChannelHandler的生命周期


在使用Netty進行網絡編程的時候,通常需要在網絡連接的不同階段進行相應的操作,比如在連接建立時,客戶端向服務端發起認證,在接收到數據時對數據內容進行解析等等。那么,連接的不同階段在netty中如何表示呢? 這便是本文討論的內容,Netty中ChannelHandller的生命周期。

首先我們先分析小網絡連接的生命周期,連接建立 ---> 數據交互 ---> 連接斷開,在數據交互階段,包括從連接中讀取數據和向連接中寫入數據。知道了連接的生命周期,就可以按圖索驥的在各個階段進行想要的操作。而在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端輸出結果如下:

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的生命周期回調接口調用順序如下:

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移除后的回調方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM