1. 程式人生 > >netty中常用概念的理解

netty中常用概念的理解

目錄

 

 


在《Netty權威指南》(第二版)中,ChannelPipelineChannelHandler

之間的關係被李林峰老師比做J2EE中的ServletFilter,即ChannelHandler的職能是網路I/O操作的過濾器。我們一起來詳細學習它們吧。


ChannelHandler

Netty API : ChannelHandler

ChannelHandler功能介紹

  • ChannelHandler的主要功能是為I/O操作進行攔截和處理,我們可以稱呼它為:I/O事件攔截器
  • 每一個Channel有擁有一個ChannelPipeline,每一個ChannelPipeline中可以包含多個ChannelHandler
  • ChannelHandler可以全部攔截也可以選擇性的攔截通過它的資訊。對攔截到的資訊加以處理後,處理的結果會被傳遞到ChannelPipeline
    中的下一個ChannelHandler中執行對應的處理。

通過ChannelHandlerAdapter自定義攔截器

雖然Netty提供了種類豐富的ChannelHandler足以應付許多場景,但在實際專案中遠遠不夠用,這時我們需要封裝自己的攔截器。
通常自定義的ChannelHandler只需要繼承ChannelHandlerAdapter並覆蓋需要用到的方法即可。

ChannelHandlerContext介面

ChannelHandlerChannelHandlerContext是一一對應的關係,ChannelPipeline並不是直接管理ChannelHandler

,而是通過ChannelHandlerContext來間接管理。ChannelHandlerContext通過以下兩個方法可以獲取到所繫結的ChannelChannelHandler

方法名 返回型別 說明
channel() Channel 返回該ChannelHandlerContext所繫結的Channel
handler() ChannelHandler 返回該ChannelHandlerContext所繫結的ChannelHandler

ChannelPipeline

Netty API : ChannelPipeline

ChannelPipeline介紹

每一個Channel都擁有自己的ChannelPipeline,它是ChannelHandler的容器,負責ChannelHandler的管理、事件攔截、訊息排程。

ChannelPipeline工作原理

ChannelPipeline實際上就是Channel的資料管道,訊息從其中通過,依次通過每個ChannelHandler並執行相應的處理。
我們通過對ChannelPipeline所持有的ChannelHandler連結串列進行簡單的增刪的操作就可以實現不同業務邏輯定製。

下圖是Netty API 中ChannelPipeline對事件流的攔截和處理流程的示意圖:

                                                 I/O Request
                                            via Channel or
                                        ChannelHandlerContext
                                                      |
  +---------------------------------------------------+---------------+
  |                           ChannelPipeline         |               |
  |                                                  \|/              |
  |    +---------------------+            +-----------+----------+    |
  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  .               |
  |               .                                   .               |
  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
  |        [ method call]                       [method call]         |
  |               .                                   .               |
  |               .                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  +---------------+-----------------------------------+---------------+
                  |                                  \|/
  +---------------+-----------------------------------+---------------+
  |               |                                   |               |
  |       [ Socket.read() ]                    [ Socket.write() ]     |
  |                                                                   |
  |  Netty Internal I/O Threads (Transport Implementation)            |
  +-------------------------------------------------------------------+

ChannelHandler的執行順序

值得注意的一點是,ChannelHandler的執行順序與向ChannelPipeline新增時的順序有關。因此,在進行類似編解碼這樣前後依賴的操作時,對ChannelHandler新增的順序要格外注意。

Netty API :
For example, let us assume that we created the following pipeline.
In the example above, the class whose name starts with Inbound means it is an inbound handler. The class whose name starts with Outbound means it is a outbound handler.

 ChannelPipeline p = ...;
 p.addLast("1", new InboundHandlerA());
 p.addLast("2", new InboundHandlerB());
 p.addLast("3", new OutboundHandlerA());
 p.addLast("4", new OutboundHandlerB());
 p.addLast("5", new InboundOutboundHandlerX());

--------------------- 本文來自 猿長大人 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/lgj123xj/article/details/78609891?utm_source=copy