服务端启动过程中并没有相关的IO事件,即事件调度层在此期间处理均为普通任务队列中的任务。
ServerBootstrap存在两个属性:childHandler & handler。childHandler为 NioSocketChannel 的pipeline编排ChannelHandler,后者是为NioServerSocketChannel的pipeline编排ChannelHandler。
NioServerSocketChannel整个生命周期只是关注Accept事件,所以针对NioServerSocketChannel通过 handler方法
为其自定义各种类型的ChannelHandler没有任何意义。
1.bind事件 & channelActive & Accept事件的关注
public abstract class AbstractBootstrap{
private ChannelFuture doBind(final SocketAddress localAddress) {
ChannelFuture regFuture = initAndRegister();
...
if (regFuture.isDone()) {
...
} else {
PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
doBind0(regFuture, channel, localAddress, promise);
}
});
return promise;
}
}
}
public abstract class AbstractChannel{
protected abstract class AbstractUnsafe implements Unsafe {
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
...
//端口绑定之前Channel尚处未激活状态
boolean wasActive = isActive();
//NioServerSocketChannel内部真正绑定端口:javaChannel().bind(localAddress, config.getBacklog());
doBind(localAddress);
//端口绑定之后Channel处于激活状态
if (!wasActive && isActive()) {
invokeLater(new Runnable() {
@Override
public void run() {
// interestOps 为Accept事件
pipeline.fireChannelActive();
}
});
}
safeSetSuccess(promise);
}
}
}
如上伪代码所示:NioServerSocketChannel完成端口绑定之后,在 NioServerSocketChannel 通过 fireChannelActive流转每个ChannelHandler过程中顺便为其SelectionKey设置感兴趣事件【interestOps】为Accept事件
。
2.ServerBootstrapAcceptor
客户端NioSocketChannel发起connect事件后,服务端事件调度层轮询过程中监听到NioServerSocketChannel对应的SelectionKey存在IO事件,即Accept事件。
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
private final class NioMessageUnsafe extends AbstractNioUnsafe {
// 字段 readBuf集合其元素类型即为 NioSocketChannel
private final List<Object> readBuf = new ArrayList<Object>();
@Override
public void read() {
assert eventLoop().inEventLoop();
final ChannelConfig config = config();
// 从 NioServerSocketChannel 得到其 ChannelPipeline
final ChannelPipeline pipeline = pipeline();
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.reset(config);
boolean closed = false;
Throwable exception = null;
do {
// 从 NioServerSocketChannel accept客户端连接对象 NioSocketChannel
int localRead = doReadMessages(readBuf);
...
allocHandle.incMessagesRead(localRead);
} while (allocHandle.continueReading());
int size = readBuf.size();
for (int i = 0; i < size; i ++) {
readPending = false;
// 执行 ChannelPipeline 维护的 channelHandler责任链
pipeline.fireChannelRead(readBuf.get(i));
}
pipeline.fireChannelReadComplete();
...
}
}
}
如上伪代码所示:NioServerSocketChannel所属的pipeline携带NioSocketChannel执行所有handler之channelRead方法。其中最为重要的就属handler之ServerBootstrapAcceptor。
public class ServerBootstrap{
private static class ServerBootstrapAcceptor extends ChannelInboundHandlerAdapter {
private final EventLoopGroup childGroup;
private final ChannelHandler childHandler;
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Channel child = (Channel) msg;//此时child即为NioSocketChannel
// 为 NioSocketChannel的pipeline编排handler
child.pipeline().addLast(childHandler);
// 线程切换
childGroup.register(child).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
forceClose(child, future.cause());
}
}
});
}
}
}
如上伪代码所示:线程切换是指bossGroup -> workGroup。从 workGroup 选择某个NioEventLoop为当前 NioSocketChannel 开启事件调度层。
后续流程即为 NioSocketChannel 的注册流程,主要即为当前channel对应的SelectionKey设置感兴趣事件【interestOps】为Read事件
,正常与客户端数据交互~
至此 bossGroup 已经完成一次Accept事件的使命,继续轮回~