本文通過(guò)源碼分析Netty是如何一步步的將接收客戶端的新連接,然后將連跟NioEventLoop綁定,并注冊(cè)相應(yīng)的Read事件。
檢測(cè)新連接
-
入口為NioEventLoop的processSelectedKey方法新連接接入的入口
-
進(jìn)入到NioMessageUnsafe的read方法NioMessageUnsafe的read方法
-
doReadMessages里會(huì)接收連接,封裝成netty里的NioSocketChannel對(duì)象NioServerSocketChannel類(lèi)里的doReadMessages
創(chuàng)建NioSocketChannel
Netty通過(guò)new 關(guān)鍵字直接創(chuàng)建NioSocketChannel。主要做了如下幾步:
-
調(diào)用AbstractNioByteChannel踢涌,傳入通過(guò)accept接收的底層channel。AbstractNioByteChannel構(gòu)造方法
-
通過(guò)AbstractNioChannel設(shè)置channel的blocking屬性為false序宦。AbstractNioChannel構(gòu)造方法
-
繼續(xù)調(diào)用父類(lèi)睁壁,構(gòu)造channel的id, unsafe與pipeline對(duì)象。AbstractChannel構(gòu)造方法
-
構(gòu)造NioSocketChannelConfig對(duì)象互捌,并通過(guò)config對(duì)象設(shè)置tcpNoDelay為true來(lái)禁止Nagle算法NioSocketChannelConfig構(gòu)造方法Nagle算法設(shè)置為false
分配線程及注冊(cè)selector
在接收完連接堡僻,并封裝成NioSocketChannel后,在NioMessageUnsafe的read方法里疫剃,通過(guò)pipeline觸發(fā)channelRead事件钉疫。注冊(cè)事件的入口
之后會(huì)在ServerBootstrapAcceptor(這個(gè)handler會(huì)在服務(wù)器bind的方法里添加到NioServerSocketChannel里)這個(gè)handler里完成如下步驟
-
添加childHandler并設(shè)置options和attrsServerBootstrapAcceptor的channelRead方法
-
通過(guò)chooser選擇完NioEventLoop后最終會(huì)調(diào)用到channel的unsafe的register方法,完成注冊(cè)操作SingleThreadEventLoop的register方法
-
綁定nioEventLoop對(duì)象巢价,并調(diào)用register0方法AbstractUnsafe人register方法
-
調(diào)用doRegister完成具體的注冊(cè)調(diào)用doRegister完成具體的注冊(cè)
-
將channel注冊(cè)到selector上AbstractNioChannel類(lèi)的doRegister方法
向selector注冊(cè)讀事件
將NioSocketChannel綁定到selector后牲阁,需要注冊(cè)相應(yīng)的I/O事件,這樣channel就能通過(guò)事件響應(yīng)業(yè)務(wù)請(qǐng)求了壤躲,chennel注冊(cè)讀事件的流程比較長(zhǎng)城菊,最終會(huì)調(diào)用到AbstractUnsafe類(lèi)的beginRead方法里:AbstractUnsafe的beginRead方法
-
最終會(huì)調(diào)用到AbstractNioChannel的doBeginRead方法里AbstractNioChannel的doBeginRead方法