當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的 生命周期方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/472851.html
標籤:Java
上一篇:Maven常用命令
