Netty原理與基礎(chǔ)(二)

5.Handler業(yè)務(wù)處理器

在Reactor反應(yīng)器經(jīng)典模型中果复,反應(yīng)器查詢到IO事件后费坊,分發(fā)到Handler業(yè)務(wù)處理器,由Handler完成IO操作和業(yè)務(wù)處理秉犹。整個的IO處理操作環(huán)節(jié)包括:從通道讀數(shù)據(jù)包殖氏、數(shù)據(jù)包解碼晚树、業(yè)務(wù)處理、目標數(shù)據(jù)編碼雅采、把數(shù)據(jù)包寫到通道爵憎,然后由通道發(fā)送到對端


image.png

用戶程序主要在Handler業(yè)務(wù)處理器中,Handler涉及的環(huán)節(jié)為:數(shù)據(jù)包解碼总滩、業(yè)務(wù)處理纲堵、目標數(shù)據(jù)編碼、把數(shù)據(jù)包寫到通道中闰渔。

從應(yīng)用程序開發(fā)人員的角度來看席函,有入站和出站兩種類型操作。
· 入站處理冈涧,觸發(fā)的方向為:自底向上茂附,Netty的內(nèi)部(如通道)到ChannelInboundHandler入站處理器正蛙。
· 出站處理,觸發(fā)的方向為:自頂向下营曼,從ChannelOutboundHandler出站處理器到Netty的內(nèi)部(如通道)乒验。

  • ChannelInboundHandler通道入站處理器


    image.png
  • ChannelOutboundHandler通道出站處理器


    image.png

5.1ChannelInitializer通道初始化處理器

通道和Handler業(yè)務(wù)處理器的關(guān)系是:一條Netty的通道擁有一條Handler業(yè)務(wù)處理器流水線,負責裝配自己的Handler業(yè)務(wù)處理器
如果向流水線中裝配業(yè)務(wù)處理器呢蒂阱?這就得借助通道的初始化類——ChannelInitializer锻全。

  • initChannel()方法是ChannelInitializer定義的一個抽象方法,這個抽象方法需要開發(fā)人員自己實現(xiàn)录煤。在父通道調(diào)用initChannel()方法時鳄厌,會將新接收的通道作為參數(shù),傳遞給initChannel()方法妈踊。initChannel()方法內(nèi)部大致的業(yè)務(wù)代碼是:拿到新連接通道作為實際參數(shù)了嚎,往它的流水線中裝配Handler業(yè)務(wù)處理器。

5.2ChannelInboundHandler的生命周期

ChannelInboundHandler的生命周期分2類:

  • 生命周期方法
    (1)handlerAdded() :當業(yè)務(wù)處理器被加入到流水線后廊营,此方法被回調(diào)歪泳。也就是在完成ch.pipeline().addLast(handler)語句之后,會回調(diào)handlerAdded()露筒。
    (2)channelRegistered():當通道成功綁定一個NioEventLoop線程后呐伞,會通過流水線回調(diào)所有業(yè)務(wù)處理器的channelRegistered()方法。(3)channelActive():當通道激活成功后邀窃,會通過流水線回調(diào)所有業(yè)務(wù)處理器的channelActive()方法荸哟。通道激活成功指的是假哎,所有的業(yè)務(wù)處理器添加瞬捕、注冊的異步任務(wù)完成,并且NioEventLoop線程綁定的異步任務(wù)完成舵抹。(4)channelInactive():當通道的底層連接已經(jīng)不是ESTABLISH狀態(tài)肪虎,或者底層連接已經(jīng)關(guān)閉時,會首先回調(diào)所有業(yè)務(wù)處理器的channelInactive()方法惧蛹。
    (5)channelUnregistered():通道和NioEventLoop線程解除綁定扇救,移除掉對這條通道的事件處理之后,回調(diào)所有業(yè)務(wù)處理器的channelUnregistered ()方法香嗓。
    (6)handlerRemoved():最后迅腔,Netty會移除掉通道上所有的業(yè)務(wù)處理器,并且回調(diào)所有的業(yè)務(wù)處理器的handlerRemoved()方法靠娱。
    -入棽琢遥回調(diào)方法
    (1)channelRead():有數(shù)據(jù)包入站,通道可讀像云。流水線會啟動入站處理流程锌雀,從前向后蚂夕,入站處理器的channelRead()方法會被依次回調(diào)到。
    (2)channelReadComplete():流水線完成入站處理后腋逆,會從前向后婿牍,依次回調(diào)每個入站處理器的channelReadComplete()方法,表示數(shù)據(jù)讀取完畢惩歉。

5.3代碼示例

public class InHandlerDemo extends ChannelInboundHandlerAdapter {
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:handlerAdded()");
        super.handlerAdded(ctx);
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:channelRegistered()");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:channelActive()");
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Logger.info("被調(diào)用:channelRead()");
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:channelReadComplete()");
        super.channelReadComplete(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:channelInactive()");
        super.channelInactive(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用: channelUnregistered()");
        super.channelUnregistered(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Logger.info("被調(diào)用:handlerRemoved()");
        super.handlerRemoved(ctx);
    }
}

測試類

public class InHandlerDemoTester {
    @Test
    public void testInHandlerLifeCircle() {
        final InHandlerDemo inHandler = new InHandlerDemo();
        //初始化處理器
        ChannelInitializer i = new ChannelInitializer<EmbeddedChannel>() {
            @Override
            protected void initChannel(EmbeddedChannel ch) {
                ch.pipeline().addLast(inHandler);
            }
        };
        //創(chuàng)建嵌入式通道
        EmbeddedChannel channel = new EmbeddedChannel(i);
        ByteBuf buf = Unpooled.buffer();
        buf.writeInt(1);
        //模擬入站等脂,寫一個入站包
        channel.writeInbound(buf);
        channel.flush();
        //模擬入站,再寫一個入站包
        channel.writeInbound(buf);
        channel.flush();
        //通道關(guān)閉
        channel.close();
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撑蚌,一起剝皮案震驚了整個濱河市慎菲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锨并,老刑警劉巖露该,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異第煮,居然都是意外死亡解幼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門包警,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撵摆,“玉大人,你說我怎么就攤上這事害晦√芈粒” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵壹瘟,是天一觀的道長鲫剿。 經(jīng)常有香客問我,道長稻轨,這世上最難降的妖魔是什么灵莲? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮殴俱,結(jié)果婚禮上政冻,老公的妹妹穿的比我還像新娘。我一直安慰自己线欲,他們只是感情好明场,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著李丰,像睡著了一般苦锨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天逆屡,我揣著相機與錄音圾旨,去河邊找鬼。 笑死魏蔗,一個胖子當著我的面吹牛砍的,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播莺治,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼廓鞠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谣旁?” 一聲冷哼從身側(cè)響起床佳,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎榄审,沒想到半個月后砌们,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡搁进,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年浪感,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饼问。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡影兽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出莱革,到底是詐尸還是另有隱情峻堰,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布盅视,位于F島的核電站捐名,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏左冬。R本人自食惡果不足惜桐筏,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一纸型、第九天 我趴在偏房一處隱蔽的房頂上張望拇砰。 院中可真熱鬧,春花似錦狰腌、人聲如沸除破。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瑰枫。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間光坝,已是汗流浹背尸诽。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盯另,地道東北人性含。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像鸳惯,于是被迫代替她去往敵國和親商蕴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353