Netty原始碼死磕(ChannelPipeline的執行過程)
阿新 • • 發佈:2022-03-15
引言
上文有提到如果Selector
輪詢到網路IO事件了,則會呼叫該Channel
對應的ChannelPipeline
來依次執行對應的ChannelHandler
。
ChannelPipeline
和ChannelHandler
的關係
那麼這裡的ChannelPipeline
和ChannelHandler
之間到底是什麼關係呢?
其實我們可以理解為類似於一個過濾器模式,其中ChannelPipeline
是一個存放各種過濾器的管道容器,而ChannelHandler
則對應著單個過濾器實體
執行流程
我們來看下ChannelPipline
的工作流程
-
NioEventLoop
觸發讀事件,會呼叫SocketChannel
ChannelPipline
- 由上一步讀取到的訊息會在
ChannelPipline
中依次被多個ChannelHandler
處理 - 處理完訊息會呼叫
ChannelHandlerContext
的write
方法傳送訊息,傳送的訊息同樣也會經過ChannelPipline
中的多個ChannelHandler
處理
上面的流程其實主要分成了兩步,觸發讀事件和寫事件。對應這兩種事件,Netty
把ChannelHandler
也分為了兩大類
-
ChannelInboundHandler
顧明思義,負責處理鏈路讀事件的Handler
。通常由IO執行緒觸發 -
ChannelOutboundHandler
Handler
也就是說當IO執行緒觸發讀事件時,只會呼叫ChannelInboundHandler
的實現handler
下面我們看下ChannelHandler
在ChannelPipline
中是一個什麼樣的結構
可以看到ChannelHandler
在加入ChannelPipline
之前會被封裝成一個ChannelHandlerContext
節點類加入到一個雙向連結串列結構中。除了頭尾兩個特殊的ChannelHandlerContext
實現類,我們自定義加入的ChannelHandler
最終都會被封裝成一個DefaultChannelHandlerContext
類。
當有讀事件被觸發時,ChannelHandler
ChannelInboundHandler
的Handler) 的觸發順序是 HeaderContext
-> TailContext
當有寫事件被觸發時,
ChannelHandler
(會篩選型別為ChannelOutboundHandler
的Handler) 的觸發順序與讀事件相反是 TailContext
-> HeaderContext
總結
本文比較簡短,主要是為了理清ChannelPipeline
和ChannelHandler
的關係,以及ChannelHandler
在ChannelPipeline
中的執行過程是怎樣的