1. 程式人生 > 其它 >netty原始碼學習之channelHander的組織管理

netty原始碼學習之channelHander的組織管理

當netty server啟動時  呼叫bind方式 時 會開始註冊serverChannel 

 有必要說下 pipeline.addLast 方法 

 它在新增一個hander的時候 會把 把這個hander包裝成 context 然後填加在 pipeline 的headContext  後面   如果沒有註冊時 會

if (!registered) {
newCtx.setAddPending();

//新增一個初始化邏輯 新增到 pipeline 裡面 在對應channel 註冊時 pipeline 會呼叫到它 (下面有分析)
callHandlerCallbackLater(newCtx, true);

return this;
}
那麼 上面那段程式碼 他是非同步的 它是什麼時候 呼叫的呢 ?

 在呼叫 register方法 時 最終會走到

io.netty.channel.AbstractChannel.AbstractUnsafe#register0 裡面

 劃線那一步 就會調到 

 上面說的那一步 一步邏輯裡面  具體的邏輯 請看後面分析   





ServerBootstrapAcceptor有什麼用呢  它繼承了  ChannelInboundHandlerAdapter  所以 當客戶端 連線伺服器時  會進入的它的read方法
下面來看 它的read方法
child.pipeline().addLast(childHandler); 這行很重要

childHandler  其實就是我們自己傳的 初始化hander 一般形式 都是  下面紅線這一塊

那麼 child 是什麼呢 其實很好理解 他就是  serverSocketChannel.accept   的到的那個 socketChannel  

現在 伺服器 在accept 之後 把 這個 socketChannel   註冊 到  workGroup中的一個 eventLoop  裡面  現在 進入   register方法裡面  

invokeHandlerAddedIfNeeded() 只會呼叫一次    在具體瞭解 這個方法的邏輯之前 我們有必要知道 pipieline的 addLast 方法的邏輯
@Override
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized (this) {
checkMultiplicity(handler);

//生成一個新的 context
newCtx = newContext(group, filterName(name, handler), handler);

//將這個context新增到head後面 head ->newContext->tail
addLast0(newCtx);

//這裡很重要 pipeline 還沒有註冊 那麼 生成一個回撥 它引用了我們剛剛生成的context 它將會在後續用到
        // If the registered is false it means that the channel was not registered on an eventLoop yet.
// In this case we add the context to the pipeline and add a task that will call
// ChannelHandler.handlerAdded(...) once the channel is registered.
if (!registered) {
newCtx.setAddPending();
callHandlerCallbackLater(newCtx, true);
return this;
}

EventExecutor executor = newCtx.executor();
if (!executor.inEventLoop()) {
callHandlerAddedInEventLoop(newCtx, executor);
return this;
}
}
callHandlerAdded0(newCtx);
return this;
}

現在進入 

private void callHandlerAddedForAllHandlers() {
final PendingHandlerCallback pendingHandlerCallbackHead;
synchronized (this) {
assert !registered;

// This Channel itself was registered.
registered = true;

//這個就是我們剛剛 新增的那個回撥 PendingHanderCallBack
        pendingHandlerCallbackHead = this.pendingHandlerCallbackHead;
// Null out so it can be GC'ed.
this.pendingHandlerCallbackHead = null;
}

// This must happen outside of the synchronized(...) block as otherwise handlerAdded(...) may be called while
// holding the lock and so produce a deadlock if handlerAdded(...) will try to add another handler from outside
// the EventLoop.
PendingHandlerCallback task = pendingHandlerCallbackHead;
while (task != null) {
//開始執行
task.execute();
task = task.next;
}
}

task.execute 其實 邏輯就是 開始執行 我們的hander的 handerAdd方法 因為我們初始化hander繼承了
io.netty.channel.ChannelInitializer
所以 下面看下它的邏輯

好 現在我們serverChannel.accept 得到的那個 channel 它的pipeline 已經 設定完畢了   繼續流程

ok 我們的accept 的 chanel註冊完畢   且對應的pipeline 也這是完畢了 也出發了 對應的channel的 生命週期方法