前言
Netty系列索引:
在Netty框架中,Channel是其中之一的核心概念,是Netty網絡通信的主體,由它負責同對端進行網絡通信、注冊和數據操作等功能。本文我們來詳細地分析 Netty 中的 Channel以及跟Channel相關的其他概念,包括ChannelPipeline、ChannelHandlerContext、ChannelHandler等
上圖簡述了數據被讀取后的處理流程,可以看出channel通過pipeline鏈接了多個Handler並依次執行,類似職責鏈模式。
Channel
目前可以把 Channel 看作是傳入(入站)或者傳出(出站)數據的通道,它可以被打開或者被關閉,連接或者斷開連接。
Netty對JDK原生的ServerSocketChannel進行了封裝和增強, 相對於原生的JdkChannel, Netty的Channel增加了如下的組件
- id 標識唯一身份信息
- 可能存在的parent Channel
- 管道 pepiline,用於鏈接handler
- 用於數據讀寫的unsafe內部類,實際IO操作都是該類實現的
- 關聯唯一的EventLoop,EventGroup->EventLoop->Channel(后續章節再講,其實就是類似線程池的東西)
channel生命周期
ChannelUnregistered | Channel 已經被創建,但還未注冊到 EventLoop |
ChannelRegistered | 已經被注冊到了 EventLoop |
ChannelActive | 處於活動狀態(已經連接到它的遠程節點)。它現在可以接收和發送數據了 |
ChannelInactive | 沒有連接到遠程節點 |
ChannelPipeline
ChannelPipeline是ChannelHandler實例對象的鏈表,用於處理或截獲通道的接收和發送數據。它提供了一種高級的截取過濾模式(類似serverlet中的filter功能),讓用戶可以在ChannelPipeline中完全控制一個事件以及如何處理ChannelHandler與ChannelPipeline的交互。
每個Channel,都會創建一個唯一的ChannelPipeline
ChannelPipeline 可以根據需要,通過添加或者刪除 ChannelHandler 來動態地修改(典型應用,動態修改協議等)
ChannelPipeline 有着豐富的 API 用以被調用,以響應入站和出站事件。
ChannelHandlerContext
ChannelHandlerContext類似上下文的概念,代表了 ChannelHandler 和 ChannelPipeline 之間的關聯,每當有 ChannelHandler 添加到 ChannelPipeline 中時,都會創建 ChannelHandlerContext。
ChannelHandlerContext 的主要功能是管理它所關聯的 ChannelHandler 和在同一個 ChannelPipeline 中的其他 ChannelHandler 之間的交互。
核心功能:
- ChannelHandlerContext使得ChannelHandler能夠和它的ChannelPipeline以及其他的ChannelHandler 交互。
- ChannelHandler 可以通知其所屬的 ChannelPipeline 中的下一個ChannelHandler
- ChannelHandlerContext 具有豐富的用於處理事件和執行 I/O 操作的 API
ChannelHandler
生命周期:
handlerAdded | 當把 ChannelHandler 添加到 ChannelPipeline 中時被調用 |
handlerRemoved | 當從 ChannelPipeline 中移除 ChannelHandler 時被調用 |
exceptionCaught | 當處理過程中在 ChannelPipeline 中有錯誤產生時被調用 |
ChannelInboundHandler 的方法
ChannelOutboundHandler 的方法
內存泄漏監控
在使用handler處理ByteBuf時,應正確處理其被引用次數,尤其是調用read和write后,應正確釋放其引用。
(注意:SimpleChannelInboundHandler會自動釋放引用)