ChannelPipline的用法

該文章基于個人的理解批什,翻譯自netty5.0 API务甥。

綜述

ChannelPipeline的作用是保存一個ChannelHandler的列表麻蹋,這些ChannelHandler用于處理或者攔截一個channel的inbound事件和outbound操作宛徊。ChannelPipeline實現(xiàn)了一個高級形式的I攔截過濾器模式歧杏,給了用戶完全的控制權來決定一個event如何被處理陪每,以及在pipeline中的channelHandler之間如何的交互影晓。

創(chuàng)建一個pipeline

每一個channel都有自己的pipeline,并且當一個新的channel被創(chuàng)建時其對應的pipeline也自動被創(chuàng)建檩禾。

event在pipeline中如何流動

下面的圖描述了I/O event如何被ChannelPipeline中的ChannelHandlers處理的典型情況挂签。一個I/O event被一個ChannelHandler處理,并被這個ChannelHandler向前遞交給其相鄰的下一個ChannelHandler盼产。如果必要的話饵婆,一個ChannelHandler同樣可以觸發(fā)一個任意的I/O event。為了遞交或者觸發(fā)一個event戏售,一個ChannelHandler調用定義在ChannelHandlerContext中的event繁殖方法侨核,比如:ChannelHandlerContext.fireChannelRead(Object)和ChannelHandlerContext.write(Object)。

ChannelPipeline中事件流動示意圖

一個inbound event被圖中左邊的ChannelHandlers從下至上地處理灌灾。一個inbound event通常被圖中底部的I/O線程所觸發(fā)搓译,以便于在Channel的狀態(tài)改變的時候(比如:新創(chuàng)建了連接和關閉了連接),或者在inbound數(shù)據(jù)被遠端讀取的時候锋喜,ChannelHandlers能夠被通知到些己。如果一個inbound event超過了圖中的頂部的范圍,那么它將根據(jù)你的日志等級決定是被拋棄還是被記錄入日志嘿般。

一個outbound event被圖中右邊的ChannelHandlers從上至下地處理段标。一個outbound event通常被你用于請求一個outbound I/O操作的代碼所觸發(fā),比如一個寫請求和一個連接的嘗試炉奴。如果一個outbound event超過了圖中ChannelHandlers底部的范圍逼庞,它將被與Channel相關的I/O線程所處理。I/O線程通常進行真正的output操作瞻赶,比如:SocketChannel.write(ByteBuffer)往堡。

將一個event向前遞交給下一個相鄰的handler

根據(jù)上面簡單的解釋械荷,一個ChannelHandler只能通過喚醒ChannelHandlerContext中event繁殖的方法,來將一個event遞交給它的下一個handler虑灰。這些方法包括:

  • Inbound event propagation methods:
    • ChannelHandlerContext.fireChannelRegistered()
    • ChannelHandlerContext.fireChannelActive()
    • ChannelHandlerContext.fireChannelRead(Object)
    • ChannelHandlerContext.fireChannelReadComplete()
    • ChannelHandlerContext.fireExceptionCaught(Throwable)
    • ChannelHandlerContext.fireUserEventTriggered(Object)
    • ChannelHandlerContext.fireChannelWritabilityChanged()
    • ChannelHandlerContext.fireChannelInactive()
  • Outbound event propagation methods:
    • ChannelHandlerContext.bind(SocketAddress, ChannelPromise)
    • ChannelHandlerContext.connect(SocketAddress, SocketAddress, ChannelPromise)
    • ChannelHandlerContext.write(Object, ChannelPromise)
    • ChannelHandlerContext.flush()
    • ChannelHandlerContext.read()
    • ChannelHandlerContext.disconnect(ChannelPromise)
    • ChannelHandlerContext.close(ChannelPromise)

下面的例子展示了event繁殖通常怎么做:

public class MyInboundHandler extends ChannelHandlerAdapter {
     @Override
     public void channelActive(ChannelHandlerContext ctx) {
         System.out.println("Connected!");
         ctx.fireChannelActive();
     }
 }

public class MyOutboundHandler extends ChannelHandlerAdapter {
     @Override
     public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
         System.out.println("Closing ..");
         ctx.close(promise);
     }
 }

創(chuàng)建一個pipeline

用戶可能有一個或多個ChannelHandlers在一個pipeline中來接收I/O events(比如:讀)和請求I/O操作(比如:寫和關閉)吨瞎。例如,一個典型的服務端在每一個channel的pipeline中都會有以下的handlers穆咐。但是你的handler的個數(shù)通常是變化的颤诀,這取決于protocol和業(yè)務邏輯的復雜性和特點:

  1. Protocol解碼器:將二進制數(shù)據(jù)(比如:ByteBuf)轉成一個Java對象。
  2. Protocol編碼器:將一個Java對象轉成二進制數(shù)據(jù)对湃。
  3. 業(yè)務邏輯相關的Handler:處理真正的業(yè)務邏輯(比如:數(shù)據(jù)庫訪問)崖叫。

這有可能像下面的例子展示的這樣:

static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
...

ChannelPipeline pipeline = ch.pipeline();

pipeline.addLast("decoder", new MyProtocolDecoder());
pipeline.addLast("encoder", new MyProtocolEncoder());

// Tell the pipeline to run MyBusinessLogicHandler's event handler methods
// in a different thread than an I/O thread so that the I/O thread is not blocked by
// a time-consuming task.
// If your business logic is fully asynchronous or finished very quickly, you don't
// need to specify a group.
pipeline.addLast(group, "handler", new MyBusinessLogicHandler());

線程安全

一個ChannelHandler在任何時候被添加或移除,因為一個ChannelPipeline是線程安全的拍柒。例如心傀,你可以在將要交換敏感信息的時候添加一個加密的handler,并在交換完畢之后移除它拆讯。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末脂男,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖霎迫,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汁讼,居然都是意外死亡,警方通過查閱死者的電腦和手機阔墩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門嘿架,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人啸箫,你說我怎么就攤上這事耸彪。” “怎么了筐高?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵搜囱,是天一觀的道長。 經(jīng)常有香客問我柑土,道長蜀肘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任稽屏,我火速辦了婚禮扮宠,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己坛增,他們只是感情好获雕,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著收捣,像睡著了一般届案。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罢艾,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天楣颠,我揣著相機與錄音,去河邊找鬼咐蚯。 笑死童漩,一個胖子當著我的面吹牛,可吹牛的內容都是我干的春锋。 我是一名探鬼主播矫膨,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼期奔!你這毒婦竟也來了侧馅?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤能庆,失蹤者是張志新(化名)和其女友劉穎施禾,沒想到半個月后脚线,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搁胆,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年邮绿,在試婚紗的時候發(fā)現(xiàn)自己被綠了渠旁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡船逮,死狀恐怖顾腊,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情挖胃,我是刑警寧澤杂靶,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站酱鸭,受9級特大地震影響吗垮,放射性物質發(fā)生泄漏。R本人自食惡果不足惜凹髓,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一烁登、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔚舀,春花似錦饵沧、人聲如沸锨络。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羡儿。三九已至,卻和暖如春是钥,著一層夾襖步出監(jiān)牢的瞬間失受,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工咏瑟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拂到,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓码泞,卻偏偏與公主長得像兄旬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子余寥,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容

  • 先簡單的了解一下BIO與NIO 下圖是幾種常見I/O模型的對比: 傳統(tǒng)的BIO里面socket.read()领铐,如果...
    可樂愛上咖啡閱讀 18,983評論 0 49
  • 前言 netty源碼分析之pipeline(一)中,我們已經(jīng)了解了pipeline在netty中所處的角色宋舷,像是一...
    簡書閃電俠閱讀 16,167評論 15 35
  • 源碼分析 NIOEventLoopGroup NioEventLoopGroup(其實是MultithreadEv...
    jiangmo閱讀 1,172評論 0 2
  • 早上绪撵,跑了10公里,最近下雨祝蝠,沒有跑音诈,今天跑完,久違的痛快感又浸潤全身绎狭,棒極了细溅! 跑步,是因為儡嘶,我對生活抱有極大的...
    陳清偉閱讀 195評論 0 0
  • 某個女孩消失 便帶走我靈魂的一塊碎片 那也是好的 愿黑夜給你不安和痛哭 我的詛咒一定毫無作用 手指沾染過的女人和男...
    卡布奇諾花蜜閱讀 574評論 0 48