Netty源碼分析第三章: 客戶端接入流程html
第五節: 監聽讀事件promise
咱們回到AbstractUnsafe的register0()方法:oop
private void register0(ChannelPromise promise) { try { //省略代碼 //作實際的註冊
doRegister(); neverRegistered = false; registered = true; //觸發事件
pipeline.invokeHandlerAddedIfNeeded(); safeSetSuccess(promise); //觸發註冊成功事件
pipeline.fireChannelRegistered(); if (isActive()) { if (firstRegistration) { //傳播active事件(4)
pipeline.fireChannelActive(); } else if (config().isAutoRead()) { beginRead(); } } } catch (Throwable t) { //省略代碼
} }
doRegister()作完實際的註冊以後, 會走到if (isActive())這個判斷, 由於這個時候鏈路已經完成, 因此這裏是true, 默認判斷條件if (firstRegistration)也爲true, 因此這裏會走到pipeline.fireChannelActive()這一步源碼分析
有關pipeline咱們會在下一章進行詳細分析, 這裏咱們只須要知道, 最後會流轉到AbstractUnsafe的beginRead()方法學習
跟到beginRead()方法:this
public final void beginRead() { assertEventLoop(); if (!isActive()) { return; } try { doBeginRead(); } catch (final Exception e) { //代碼省略
} }
這塊代碼一樣咱們也不陌生, 由於咱們分析NioServerSocketChannel也分析過了這一步spa
咱們繼續跟到doBeginRead():debug
protected void doBeginRead() throws Exception { //拿到selectionKey
final SelectionKey selectionKey = this.selectionKey; if (!selectionKey.isValid()) { return; } readPending = true; //得到感興趣的事件
final int interestOps = selectionKey.interestOps(); //判斷是否是對任何事件都不監聽
if ((interestOps & readInterestOp) == 0) { //此條件成立 //將以前的accept事件註冊, readInterest表明能夠讀取一個新鏈接的意思
selectionKey.interestOps(interestOps | readInterestOp); } }
這段代碼相信你們會比較熟悉, 由於咱們服務端channel註冊完以後也走到了這裏rest
由於咱們在建立NioSocketChannel的時候初始化的是read事件, selectionKey是channel在註冊時候返回的key, 因此selectionKey.interestOps(interestOps | readInterestOp)這一步, 會將當前channel的讀事件註冊到selector中去code
註冊完成以後, NioEventLoop就能夠輪詢當前channel的讀事件了
以上就是NioSocketChannel註冊監聽事件的流程
第三章總結
本章學習了有關客戶端接入, NioSocketChannel的建立, 註冊等相關操做, 而且涉及到了上一小節剖析的eventLoop的相關邏輯, 同窗們能夠將相關的流程經過debug的方式走一遍以加深印象