百木园-与人分享,
就是让自己快乐。

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的 生命周期方法   

 

 

 

 

 

 



 


来源:https://www.cnblogs.com/pupansheng/p/16261826.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » netty源码学习之channelHander的组织管理

相关推荐

  • 暂无文章