天天看點

Netty4——Handler執行順序

Netty4中, I / O事件由ChannelInboundHandler或ChannelOutboundHandler處理,并通過調用ChannelHandlerContext中定義的事件傳播方法(如ChannelHandlerContext.fireChannelRead(Object)和ChannelHandlerContext.write(Object))轉發給其最接近的處理程式。

補充說明:Netty4中的所有handler都實作自ChannelHandler接口。按照輸出輸出來分,分為ChannelInboundHandler、ChannelOutboundHandler兩大類。ChannelInboundHandler對從用戶端發往伺服器的封包進行處理,一般用來執行解碼、讀取用戶端資料、進行業務處理等;ChannelOutboundHandler對從伺服器發往用戶端的封包進行處理,一般用來進行編碼、發送封包到用戶端。

下圖描述了ChannelPipeline中的ChannelHandlers如何處理I / O事件。

Netty4——Handler執行順序

Inbound(入站)事件由Inbound處理程式以自下而上的方向處理,如圖所示。Inbound處理程式通常處理由圖底部的I / O線程生成的Inbound資料。 Inbound資料通常通過實際的輸入操作(如SocketChannel.read(ByteBuffer))從遠端對等端讀取。 如果Inbound事件超出頂層入站處理程式,它将被靜默放棄,或者在需要您關注時進行記錄。

一個Outbound(出站)事件由Outbound處理程式在自上而下的方向進行處理,如圖所示。Outbound處理程式通常會生成或轉換Outbound流量,如寫入請求。 如果出站事件超出底部出站處理程式,則由與該通道關聯的I / O線程處理。 I / O線程經常執行實際的輸出操作,例如SocketChannel.write(ByteBuffer)。

例如,假設我們建立了以下管道:

 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());

在上面的例子中,名稱以Inbound開頭的類意味着它是一個入站處理程式。名稱以Outbound開頭的類表示它是出站處理程式。

在給定的示例配置中,當事件進入時,處理程式評估順序為1,2,3,4,5。當事件出站時,順序為5,4,3,2,1。在此原則之上,ChannelPipeline跳過某些處理程式的評估以縮短堆棧深度:

    3和4不實作ChannelInboundHandler,是以入站事件的實際評估順序将為:1,2和5。

    1和2不實作ChannelOutboundHandler,是以出站事件的實際評估順序将為:5,4和3。

    如果5實作ChannelInboundHandler和ChannelOutboundHandler,則入站和出站事件的評估順序可分别為125和543。