netty4 client連接服務端步驟及底層原理說明

服務端依次發生的步驟

  1. 建立服務端監聽套接字ServerSocketChannel,以及對應的管道pipeline;
  2. 啓動boss線程,將ServerSocketChannel註冊到boss線程持有的selector中,並將註冊返回的selectionKey賦值給ServerSocketChannel關聯的selectionKey變量;
  3. 在ServerSocketChannel對應的管道中觸發channelRegistered事件;
  4. 綁定IP和端口
  5. 觸發channelActive事件,並將ServerSocketChannel關聯的selectionKey的OP_ACCEPT位置爲1。
  6. 客戶端發起connect請求後,boss線程正在運行的select循環檢測到了該ServerSocketChannel的ACCEPT事件就緒,則通過accept系統調用建立一個已連接套接字SocketChannel,併爲其創建對應的管道;
  7. 在服務端監聽套接字對應的管道中觸發channelRead事件;
  8. channelRead事件由ServerBootstrapAcceptor的channelRead方法響應:爲已連接套接字對應的管道加入ChannelInitializer處理器;啓動一個worker線程,並將已連接套接字的註冊任務加入到worker線程的任務隊列中;
  9. worker線程執行已連接套接字的註冊任務:將已連接套接字註冊到worker線程持有的selector中,並將註冊返回的selectionKey賦值給已連接套接字關聯的selectionKey變量;在已連接套接字對應的管道中觸發channelRegistered事件;channelRegistered事件由ChannelInitializer的channelRegistered方法響應:將自定義的處理器(譬如EchoServerHandler)加入到已連接套接字對應的管道中;在已連接套接字對應的管道中觸發channelActive事件;channelActive事件由已連接套接字對應的管道中的inbound處理器的channelActive方法響應;將已連接套接字關聯的selectionKey的OP_READ位置爲1;至此,worker線程關聯的selector就開始監聽已連接套接字的READ事件了。
  10. 在worker線程運行的同時,Boss線程接着在服務端監聽套接字對應的管道中觸發channelReadComplete事件。
  11. 客戶端向服務端發送消息後,worker線程正在運行的selector循環會檢測到已連接套接字的READ事件就緒。則通過read系統調用將消息從套接字的接受緩衝區中讀到AdaptiveRecvByteBufAllocator(可以自適應調整分配的緩存的大小)分配的緩存中;
  12. 在已連接套接字對應的管道中觸發channelRead事件;
  13. channelRead事件由EchoServerHandler處理器的channelRead方法響應:執行write操作將消息存儲到ChannelOutboundBuffer中;
  14. 在已連接套接字對應的管道中觸發ChannelReadComplete事件;
  15. ChannelReadComplete事件由EchoServerHandler處理器的channelReadComplete方法響應:執行flush操作將消息從ChannelOutboundBuffer中flush到套接字的發送緩衝區中;

 

客戶端依次發生的步驟

  1. 建立套接字SocketChannel,以及對應的管道pipeline;
  2. 啓動客戶端線程,將SocketChannel註冊到客戶端線程持有的selector中,並將註冊返回的selectionKey賦值給SocketChannel關聯的selectionKey變量;
  3. 觸發channelRegistered事件;
  4. channelRegistered事件由ChannelInitializer的channelRegistered方法響應:將客戶端自定義的處理器(譬如EchoClientHandler)按順序加入到管道中;
  5. 向服務端發起connect請求,並將SocketChannel關聯的selectionKey的OP_CONNECT位置爲1;
  6. 開始三次握手,客戶端線程正在運行的select循環檢測到了該SocketChannel的CONNECT事件就緒,則將關聯的selectionKey的OP_CONNECT位置爲0,再通過調用finishConnect完成連接的建立;
  7. 觸發channelActive事件;
  8. channelActive事件由EchoClientHandler的channelActive方法響應,通過調用ctx.writeAndFlush方法將消息發往服務端;
  9. 首先將消息存儲到ChannelOutboundBuffer中;(如果ChannelOutboundBuffer存儲的所有未flush的消息的大小超過高水位線writeBufferHighWaterMark(默認值爲64 * 1024),則會觸發ChannelWritabilityChanged事件)
  10. 然後將消息從ChannelOutboundBuffer中flush到套接字的發送緩衝區中;(如果ChannelOutboundBuffer存儲的所有未flush的消息的大小小於低水位線,則會觸發ChannelWritabilityChanged事件)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章