圖解Netty之Pipeline、channel、Context之間的數據流向。


      聲明:本文為原創博文,禁止轉載。

      以下所繪制圖形均基於Netty4.0.28版本。

一、connect(outbound類型事件)

     當用戶調用channel的connect時,會發起一個outbound類型的事件,該事件將在pipeline中傳遞(pipeline.connect),首先由tail handler處理,該handler只是將事件透傳給下一個outbound類型的用戶Handler(如果有),事件依次傳遞下去,直到傳遞到head handler,該handler會調用unsafe.connect()向eventloop(nio的selector)注冊一個讀事件。 

 

 二、connect成功之后數據流圖(inbound類型事件)

      當用戶發起一個connect請求后,當連接可用時,eventloop(底層使用nio的selector)會引發一個ChannelActive事件,該事件最先有unsafe捕獲,之后會調用pipeline.fireChannelActive()將該事件在pipeline中傳播,緊接着會根據inbound類型事件的傳遞方式在各個handler和context之間進行鏈式傳遞。其中,有一個比較關注的地方是,在channelActive事件觸發的時候,如果channel被設置成autoRead,那么此時還會調用channel.read()方法,該方法並不是真正的從channel讀取數據,而是向eventloop注冊讀事件(因為一個channel在向eventloop中注冊時,默認不注冊任何事件),關於channel.read的過程可以看下文的另一張圖。

 

 

三、channel.read事件流圖(outbound類型事件)

      當用戶調用channel.read()后,會發起一個outbound類型的事件,該事件最先會由pipeline中tail handler處理,該handler只是將該事件透傳給前面一個outbound類型的用戶handler(如果有的話),這樣依次繼續向前傳遞,直到傳遞到head handler,該handler會調用unsafe.read()向eventloop注冊讀事件(也就是向nio的selector上添加讀事件)

 

 

四、channel.write(outbound類型事件)

     與channel.read()類型,wirte也是一個outbound類型事件,該事件最先會由pipeline中的tail handler透傳給前面的一個outbound類型的用戶handler(如果有的話),這樣依次傳遞,直到傳遞給head handler,該handler會調用unsafe.write()方法,這里的wirte並不會執行真正的發送,而是將要發送的數據緩存起來,直到調用flush時,這些數據才會執行真正的網絡io。 

 五、flush(outbound類型事件)

     如前文所示,flush也是一個outbound類型的事件,與wirte不同,flush會執行真正的網絡io操作。

 

 

 

六、當channel有數據可讀時(inbound類型事件)

     當eventloop層檢測到網絡層有數據可讀時(nio的selector返回相應的seleciontKeys),該事件會首先傳遞給unsafe,緊接着會調用pipeline.fireChannelRead(),將事件開始在pipeline中傳遞,該事件最先會有head handler處理(head.fireChannelRead()),該handler直接將事件透傳給下一個inbound類型的用戶handler(如果有的話),該事件依次向下傳遞,直到傳遞到tail handler。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM