Netty源码解析 -- 服务端启动过程 (4)

#1 注意msg参数,就是NioServerSocketChannel#doReadMessages方法中生成的NioSocketChannel。
上面说了,ServerBootstrap#init方法中会将ServerBootstrap中SocketChannel相关配置交给ServerBootstrapAcceptor。
这里配置NioSocketChannel的Options,Attribute,并将childHandler添加给pipeline。
#2 将NioSocketChannel注册到ReadGroup中,注册过程类似于NioServerSocketChannel注册到AcceptGroup,调用AbstractUnsafe#register方法实现。
但有一点不同,调用AbstractNioChannel#doBeginRead方法注册关注事件时,关注事件(即AbstractNioChannel#readInterestOp),是来自子类AbstractNioByteChannel#构造方法,固定为SelectionKey.OP_READ。
到这里,(jvm)SocketChannel已经注册到ReadGroupo维护中(jvm)Selector,关注的事件Key为read。

延迟任务

前面说了,ServerBootstrap#init方法#2步骤中ChannelInitializer#initChannel方法由延迟任务触发。现在看一下延迟任务的实现。

添加延迟任务
DefaultChannelPipeline#addFirst

public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) { final AbstractChannelHandlerContext newCtx; synchronized (this) { checkMultiplicity(handler); name = filterName(name, handler); // #1 newCtx = newContext(group, name, handler); addFirst0(newCtx); // #2 if (!registered) { newCtx.setAddPending(); callHandlerCallbackLater(newCtx, true); return this; } // #3 EventExecutor executor = newCtx.executor(); if (!executor.inEventLoop()) { callHandlerAddedInEventLoop(newCtx, executor); return this; } } callHandlerAdded0(newCtx); return this; }

#1 构造一个ChannelHandlerContext并添加到拦截链表首部位置
#2 当前Channel未注册,调用DefaultChannelPipeline#callHandlerCallbackLater,添加一个延迟任务
#3 当前Channel已注册,调用DefaultChannelPipeline#callHandlerAdded0,完成ChannelHandler添加扩展操作。

DefaultChannelPipeline#callHandlerCallbackLater方法,将当前ChannelHandlerContext转化为一个延迟任务PendingHandlerAddedTask或者PendingHandlerRemovedTask,加到DefaultChannelPipeline#pendingHandlerCallbackHead列表中。
DefaultChannelPipeline#addLast/removeFirst/removeLast同样有类似处理延迟任务的逻辑。

执行延迟任务
AbstractUnsafe#register0方法#2步骤 -> DefaultChannelPipeline#callHandlerAddedForAllHandlers,该方法会执行pendingHandlerCallbackHead列表所有任务,调用其execute方法。
PendingHandlerAddedTask#execute会调用ChannelHandler#handlerAdded,完成ChannelHandler添加扩展工作。
PendingHandlerRemovedTask#execute则调用ChannelHandler#handlerRemoved,完成ChannelHandler移除善后工作。

ServerBootstrap#init方法#2步骤给ServerChannel的ChannelPipeline添加一个ChannelInitializer,它是Netty提供的工具类,实现了ChannelHandler#handlerAdded方法,实现逻辑是如果当前Channel已注册,则调用initChannel方法,否则不处理(所以我们常常利用该接口在注册完成后添加新的ChannelHandler给ChannelHandler)。

回到ServerBootstrap#init方法,由于该方法执行时Channel未注册,所以会生成延迟任务,由AbstractUnsafe#register0方法#2步骤触发完成实际操作,将ServerBootstrapAcceptor添加到ServerChannel的ChannelPipeline中。

最后说一下本文提到的netty组件。
Channel,通信通道,是Netty通信的基础组件。
EventLoop,ChannelPipeline是Netty中比较重要的组件,后面有对应的文章解析。
Unsafe负责实际数据传输工作,在解析Netty流程时会注解介绍它。
ChannelFuture,ChannelPromise代表Netty异步IO结果,通过回调函数执行后续操作。

如果您觉得本文不错,欢迎关注我的微信公众号,后续提供系列文章pdf下载。您的关注是我坚持的动力!

Netty源码解析 -- 服务端启动过程

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjzf.html