借用网络上一张netty流程图 而我们今天要分析的ServerBootstrapAcceptor功能就是红色标注的这一块:netty是如何将bossGroup中接收到的SocketChannel注册到workerGroup的Selector之上。
ServerBootstrapAcceptor在io.netty.bootstrap.AbstractBootstrap#bind(int)方法,具体在io.netty.bootstrap.ServerBootstrap#init方法中,被添加到了bossGroup中的pipeline中
//初始化
void init(Channel channel) {//channel 是NioServerSocketChannel
setChannelOptions(channel, newOptionsArray(), logger);
setAttributes(channel, newAttributesArray());
ChannelPipeline p = channel.pipeline();//pipeline在调用构造函数时候创建即DefaultChannelPipeline pipeline即handler组成的责任链
final EventLoopGroup currentChildGroup = childGroup;//childGroup即workGroup
final ChannelHandler currentChildHandler = childHandler;//childHandler即main方法里面childHandler设置的Handler处理器
final Entry<ChannelOption<?>, Object>[] currentChildOptions = newOptionsArray(childOptions);//childOptions设置的属性
final Entry<AttributeKey<?>, Object>[] currentChildAttrs = newAttributesArray(childAttrs);//childAttr设置的属性
//pipeline即链表组成的责任链 addlast即添加到链表尾部 initChannel等待回调
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(final Channel ch) {
final ChannelPipeline pipeline = ch.pipeline();//ch还是NioSeverSocketChannel
ChannelHandler handler = config.handler();
if (handler != null) {
pipeline.addLast(handler);
}
//netty重写了execute方法 io.netty.util.concurrent.SingleThreadEventExecutor.execute(java.lang.Runnable)
// 这时做了两件事:1.添加任务队列到taskQueue,BossGroup线程自旋然后再处理taskQueue的run方法 也就是在bossGroup的线程中 执行的run方法并将ServerBootstrapAcceptor添加到pipeline当中 等待后续回调
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
//异步往pipeline中添加新的handler 在创建ServerBootstrapAcceptor对象时候 传入了childGroup以及childHandler等等参数
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
}
再创建ServerBootstrapAcceptor对象时候 传入了childGroup以及childHandler等等参数,这些参数我们在启动netty时候会设置
io.netty.bootstrap.ServerBootstrap.ServerBootstrapAcceptor#channelRead方法我们知道 在bossGroup的线程自旋时回调,然后通过EventExecutorChooser对象获取到下一个workGroup中的线程,启动workGroup线程,并将SocketChannel注册到workerGroup的selector并监听相关读事件
public void channelRead(ChannelHandlerContext ctx, Object msg) {
//NioSocketChannel也就是客户端的channel都注册到workGroup上
final Channel child = (Channel) msg;
//给workGroup的popeline 添加处理handler childHandler是main方法里面添加
child.pipeline().addLast(childHandler);
setChannelOptions(child, childOptions, logger);
setAttributes(child, childAttrs);
try {
//注册channel 并添加监听器 着重看register方法
childGroup.register(child).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
forceClose(child, future.cause());
}
}
});
} catch (Throwable t) {
forceClose(child, t);
}
}
io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel)
通过Chooser获取到下一个执行任务的workerGroup线程
public ChannelFuture register(Channel channel) {
return next().register(channel);//调用io.netty.channel.SingleThreadEventLoop.register(io.netty.channel.Channel)
}
io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel)
public ChannelFuture register(Channel channel) {
//1.创建DefaultChannelPromise的对象 DefaultChannelPromise即可以操作返回结果的future对象
//2。调用register方法
return register(new DefaultChannelPromise(channel, this));
}
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);//通过unsafe对象调用register方法
return promise;
}
io.netty.channel.AbstractChannel.AbstractUnsafe#register 进入了register方法 前面文章已经分析过register方法,也就是拿到了BossGroup中拿到的客户端SocketChannel注册到worker线程的Selector上
bossGroup、workerGroup线程又是如何自旋 如何执行对应的任务呢 这都是在io.netty.channel.nio.NioEventLoop中执行的 接下来会分析到