本節主要介紹 Netty ChannelHandler 事件概述,并詳細介紹各個事件方法的觸發時機,為下篇關于事件傳播機制打下堅實基礎,
NIO 相關的核心類圖如下:

下面一一對上述類做一個簡單的介紹,下文還會其進行更為詳細的解讀,
- ChannelHandler
Netty Channel事件的基礎介面,只定義與 Handler 的管理介面相關,具體如下:- void handlerAdded(ChannelHandlerContext ctx)
在呼叫 DefaultChannelPipeline 的 addLast(add*) 將事件監聽器添加到事件處理鏈條時呼叫, - void handlerRemoved(ChannelHandlerContext ctx)
在呼叫DefaultChannelPipeline 的 addLast(add*) 發生例外時被呼叫;當通道關閉后,通道取消注冊后,同時會觸發通道移除事件,具體呼叫入口:DefaultChannelPipeline 的內部類 HeadContext 的 channelUnregistered,
- void handlerAdded(ChannelHandlerContext ctx)
- ChannelInboundHandler
入端型別的事件處理器,- void channelRegistered(ChannelHandlerContext ctx)
通道注冊到 Selector 時觸發,客戶端在呼叫 connect 方法,通過 TCP 建立連接后,獲取 SocketChannel 后將該通道注冊在 Selector 時或服務端在呼叫bind 方法后創建 ServerSocketChannel,通過將通道注冊到 Selector 時監聽客戶端連接上時被呼叫, - void channelUnregistered(ChannelHandlerContext ctx)
通道取消注冊到Selector時被呼叫,通常在通道關閉時觸發,首先觸發channelInactive 事件,然后再觸發 channelUnregistered 事件, - void channelActive(ChannelHandlerContext ctx)
通道處于激活的事件,在 Netty 中,處于激活狀態表示底層 Socket 的isOpen() 方法與 isConnected() 方法回傳 true, - void channelInactive(ChannelHandlerContext ctx)
通道處于非激活(關閉),呼叫了 close 方法時,會觸發該事件,然后觸發channelUnregistered 事件, - void channelRead(ChannelHandlerContext ctx, Object msg)
通道從對端讀取資料,當事件輪詢到讀事件,呼叫底層 SocketChanne 的 read 方法后,將讀取的位元組通過事件鏈進行處理,NIO 的觸發入口為AbstractNioByteChannel 的內部類 NioByteUnsafe 的 read 方法, - void channelReadComplete(ChannelHandlerContext ctx)
處理完一次通道讀事件后觸發,在 Netty 中一次讀事件處理中,會多次呼叫SocketChannel 的 read方法,觸發入口為AbstractNioByteChannel 的內部類NioByteUnsafe 的 read 方法, - void userEventTriggered(ChannelHandlerContext ctx, Object evt)
觸發用戶自定義的事件,目前只定義了ChannelInputShutdownEvent(如果允許半關閉(輸入端關閉而服務端不關閉))事件, - void channelWritabilityChanged(ChannelHandlerContext ctx)
Netty 寫快取區可寫狀態變更事件(可寫–》不可寫、不可寫–》可寫),入口訊息發送快取區ChannelOutboundBuffer,
- void channelRegistered(ChannelHandlerContext ctx)
- void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
例外事件, - ChannelOutboundHandler
出端型別的事件處理器,- void bind(ChannelHandlerContext ctx, SocketAddress add, ChannelPromise p)
呼叫ServerBootstrap 的 bind 方法的處理邏輯,系結操作,服務端在啟動時呼叫bind方法時觸發(手動呼叫bind), - void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)
連接操作,客戶端啟動時呼叫connect方法時觸發(手動呼叫connect), - void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
斷開連接操作(手動呼叫disconnect) - void close(ChannelHandlerContext ctx, ChannelPromise promise)
關閉通道,手動呼叫Channel#close方法時觸發,(手動呼叫close) - void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
呼叫Channel#deregister時觸發,(手動呼叫deregister), - void read(ChannelHandlerContext ctx) throws Exception
注冊讀事件,并不是觸發網路讀寫事件, - void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
呼叫呼叫 Channel 的 write(底層 SocketChannel 的 write)時觸發, - void flush(ChannelHandlerContext ctx)
呼叫呼叫Channel#flush(SocketChannel#flush)時觸發,
- void bind(ChannelHandlerContext ctx, SocketAddress add, ChannelPromise p)
- ChannelDuplexHandler
雙向 Handler,包含 Inbound 和 outbound 事件, - ByteToMessageDecoder
解碼器:位元組流解碼成一條一條的訊息(Message、協議物件), - MessageToByteEncoder
編碼器:訊息(協議物件)編碼成二進制位元組流, - AbstractTrafficShapingHandler
流量整形,將在后續章節中詳細介紹,
上述詳細的介紹了NettyChannel的類繼承體系,并重點介紹了ChannelInboundHandler 與 ChannelOutboundHandler 每個方法的含義已經觸發時機,接下來再談一點我對這兩個 Handler 的一些理解,
ChannelInboundHandler:入端操作,可以看出基本上是都是由事件選擇器(NIO Selector事件就緒選擇)進行觸發,事件名稱以 channel 開頭,例如channelRead,
ChannelOutboundHanlder:出端操作,其觸發點除了 read 事件外都是通過呼叫api(例如bind、connect、close、write),
本文就介紹到這里了,主要目的是讓大家對 Netty ChannelHandler 有一個基本的認識,為后續文章打下堅實的基礎,
最后以一個思考題結束本文的講解:ChannelInboundHandler 的channelRead 事件與 ChannelOutboundHandler 的 read 事件有什么區別呢?
溫馨提示:如果需要與筆者關于上述問題進行交流,可以加筆者微信:dingwpmz,
好了,本文就介紹到這里了,您的點贊與轉發是對我持續輸出高質量文章最大的鼓勵,
歡迎加筆者微信號(dingwpmz),拉您如技術交流加群探討,筆者優質專欄目錄:
1、原始碼分析RocketMQ專欄(40篇+)
2、原始碼分析Sentinel專欄(12篇+)
3、原始碼分析Dubbo專欄(28篇+)
4、原始碼分析Mybatis專欄
5、原始碼分析Netty專欄(18篇+)
6、原始碼分析JUC專欄
7、原始碼分析Elasticjob專欄
8、Elasticsearch專欄(20篇+)
9、原始碼分析MyCat專欄
10、原始碼分析 Canal
11、原始碼分析Kafka
CSDN認證博客專家
RocketMQ
資深架構師
中間件興愛好者
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/232635.html
標籤:AI
