本文通過源碼分析Netty是如何一步步的將接收客戶端的新連接,然後將連跟NioEventLoop綁定,並註冊相應的Read事件。
檢測新連接
- 入口爲NioEventLoop的processSelectedKey方法
- 進入到NioMessageUnsafe的read方法
- doReadMessages裏會接收連接,封裝成netty裏的NioSocketChannel對象
創建NioSocketChannel
Netty通過new 關鍵字直接創建NioSocketChannel。主要做了如下幾步:
- 調用AbstractNioByteChannel,傳入通過accept接收的底層channel。
- 通過AbstractNioChannel設置channel的blocking屬性爲false。
- 繼續調用父類,構造channel的id, unsafe與pipeline對象。
- 構造NioSocketChannelConfig對象,並通過config對象設置tcpNoDelay爲true來禁止Nagle算法
分配線程及註冊selector
在接收完連接,並封裝成NioSocketChannel後,在NioMessageUnsafe的read方法裏,通過pipeline觸發channelRead事件。之後會在ServerBootstrapAcceptor(這個handler會在服務器bind的方法裏添加到NioServerSocketChannel裏)這個handler裏完成如下步驟
- 添加childHandler並設置options和attrs
- 通過chooser選擇完NioEventLoop後最終會調用到channel的unsafe的register方法,完成註冊操作
- 綁定nioEventLoop對象,並調用register0方法
- 調用doRegister完成具體的註冊
- 將channel註冊到selector上
向selector註冊讀事件
將NioSocketChannel綁定到selector後,需要註冊相應的I/O事件,這樣channel就能通過事件響應業務請求了,chennel註冊讀事件的流程比較長,最終會調用到AbstractUnsafe類的beginRead方法裏:- 最終會調用到AbstractNioChannel的doBeginRead方法裏