標籤:預設值 nis 緩衝 channel 通訊端 通過 pipeline 發送 echo
轉載:http://xw-z1985.iteye.com/blog/1973205
服務端依次發生的步驟
- 建立服務端監聽通訊端ServerSocketChannel,以及對應的管道pipeline;
- 啟動boss線程,將ServerSocketChannel註冊到boss線程持有的selector中,並將註冊返回的selectionKey賦值給ServerSocketChannel關聯的selectionKey變數;
- 在ServerSocketChannel對應的管道中觸發channelRegistered事件;
- 綁定IP和連接埠
- 觸發channelActive事件,並將ServerSocketChannel關聯的selectionKey的OP_ACCEPT位置為1。
- 用戶端發起connect請求後,boss線程正在啟動並執行select迴圈檢測到了該ServerSocketChannel的ACCEPT事件就緒,則通過accept系統調用建立一個已串連通訊端SocketChannel,並為其建立對應的管道;
- 在服務端監聽通訊端對應的管道中觸發channelRead事件;
- channelRead事件由ServerBootstrapAcceptor的channelRead方法響應:為已串連通訊端對應的管道加入ChannelInitializer處理器;啟動一個worker線程,並將已串連通訊端的註冊任務加入到worker線程的任務隊列中;
- worker線程執行已串連通訊端的註冊任務:將已串連通訊端註冊到worker線程持有的selector中,並將註冊返回的selectionKey賦值給已串連通訊端關聯的selectionKey變數;在已串連通訊端對應的管道中觸發channelRegistered事件;channelRegistered事件由ChannelInitializer的channelRegistered方法響應:將自訂的處理器(譬如EchoServerHandler)加入到已串連通訊端對應的管道中;在已串連通訊端對應的管道中觸發channelActive事件;channelActive事件由已串連通訊端對應的管道中的inbound處理器的channelActive方法響應;將已串連通訊端關聯的selectionKey的OP_READ位置為1;至此,worker線程關聯的selector就開始監聽已串連通訊端的READ事件了。
- 在worker線程啟動並執行同時,Boss線程接著在服務端監聽通訊端對應的管道中觸發channelReadComplete事件。
- 用戶端向服務端發送訊息後,worker線程正在啟動並執行selector迴圈會檢測到已串連通訊端的READ事件就緒。則通過read系統調用將訊息從通訊端的接受緩衝區中讀到AdaptiveRecvByteBufAllocator(可以自適應調整分配的緩衝的大小)分配的緩衝中;
- 在已串連通訊端對應的管道中觸發channelRead事件;
- channelRead事件由EchoServerHandler處理器的channelRead方法響應:執行write操作將訊息儲存到ChannelOutboundBuffer中;
- 在已串連通訊端對應的管道中觸發ChannelReadComplete事件;
- ChannelReadComplete事件由EchoServerHandler處理器的channelReadComplete方法響應:執行flush操作將訊息從ChannelOutboundBuffer中flush到通訊端的發送緩衝區中;
用戶端依次發生的步驟
- 建立通訊端SocketChannel,以及對應的管道pipeline;
- 啟動用戶端線程,將SocketChannel註冊到用戶端線程持有的selector中,並將註冊返回的selectionKey賦值給SocketChannel關聯的selectionKey變數;
- 觸發channelRegistered事件;
- channelRegistered事件由ChannelInitializer的channelRegistered方法響應:將用戶端自訂的處理器(譬如EchoClientHandler)按順序加入到管道中;
- 向服務端發起connect請求,並將SocketChannel關聯的selectionKey的OP_CONNECT位置為1;
- 開始三向交握,用戶端線程正在啟動並執行select迴圈檢測到了該SocketChannel的CONNECT事件就緒,則將關聯的selectionKey的OP_CONNECT位置為0,再通過調用finishConnect完成串連的建立;
- 觸發channelActive事件;
- channelActive事件由EchoClientHandler的channelActive方法響應,通過調用ctx.writeAndFlush方法將訊息發往服務端;
- 首先將訊息儲存到ChannelOutboundBuffer中;(如果ChannelOutboundBuffer儲存的所有未flush的訊息的大小超過高水位線writeBufferHighWaterMark(預設值為64 * 1024),則會觸發ChannelWritabilityChanged事件)
- 然後將訊息從ChannelOutboundBuffer中flush到通訊端的發送緩衝區中;(如果ChannelOutboundBuffer儲存的所有未flush的訊息的大小小於低水位線,則會觸發ChannelWritabilityChanged事件)
netty4 連通步驟