当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.cnblogs.com/pupansheng/p/16261826.html
本站部分图文来源于网络,如有侵权请联系删除。