設為「星標」,好文章不錯過!
boss thread
NioEventLoop 中的 selector輪詢創建連接事件 (ОР_АССЕРT)創建 socket channel初始化 socket channel 並從 worker group 中選擇一個 NioEventLoopworker thread
將socket channel註冊到選擇的NioEventLoop的selector註冊讀事件(OP_ READ)到selector 上接收連接請求的處理本質是對 OP_ACCEPT 的處理,即在 NioEventLoop 中,因為註冊到了NioEventLoop的 selector。分別調試啟動 EchoServer 和 EchoClient
跳至對應 handler
當前為 bosseventloop,不是 workereventloop
所以這裡 false,又來到註冊
創建完連接後了,已經可以開始接收數據了,即準備讀數據了
最後觀察下 server 的日誌信息
前5行都是服務啟動,後面的就是為了創建連接服務啟動過程多了個 bind 過程,且只綁定了一個接口,而對於下面的創建連接過程它有兩個埠:客戶端埠+server 監聽的埠,這就是 socketChannel接收連接的核心代碼
// 阻塞輪詢。非阻塞輪詢。超時等待輪詢selector.select()/ selectNow()/select(timeoutMillis) 發現 OP_ACCEPT 事件,處理:SocketChannel socketChannel = serverSocketChannel.accept()selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);selectionKey.interestOps(OP_READ);
創建連接的初始化和註冊是通過pipeline.fireChannelRead在ServerBootstrapAcceptor中完成
第一次Register並非監聽OP_READ,而是0
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this)
最終監聽OP_READ是通過"Register"完成後的fireChannelActive(io.netty.channel.AbstractChannel.AbstractUnsafe#register0)觸發
Worker’s NioEventLoop是通過Register操作執行來啟動。
接受連接的讀操作,不會嘗試讀取更多次(16次)。因為無法知道後續是否還有連接,不可能一直嘗試。