目录
前言
web请求连接建立
Netty的web服务端建立以后,具备了监听客户端连接的功能,在NioEventLoop的run方法中。且reactor-http-nio-1线程停留在strategy = select(curDeadlineNanos);
方法中,但该线程没有阻塞。
放开断点后,观察到线程reactor-http-nio-1
没有再次进入到finally
处的断点:
此时,前端输入请求地址:
观察线程重新进入断点:
以上四副图中,揭示了链接发起到被Netty服务端建立和监听到的完整过程。
客户端与服务端的连接建立
这一过程实现了客户端到服务端的连接建立。会再次进入服务端时的Socket的注册过程。
判断此时NioServerSocketChannel的状态位,为16【SelectionKey.OP_ACCEPT】。表达的含义是此时从Selector中就绪的NioServerSocketChannel,正在接收客户端的连接。

unsafe.read()
操作实现客户端与服务端的连接建立或者接收客户端的请求信息工作。通过SocketChannel ch = SocketUtils.accept(javaChannel());
来获取到客户端的套接字SocketChannel
对象,这里是不是与Socket编程一模一样?【但的确是用较少的线程和Selector实现了同样的Socket通信功能】。
这里注意一下,怎么实现客户端和服务端的连接对应关系?buf.add(new NioSocketChannel(this, ch));
中的this指的是本次被Selector选择到的NioServerSocketChannel,以便服务端知道响应客户端通道。这一过程,是由pipeline.fireChannelRead(readBuf.get(i));
来触发。
在findContextInbound
中获取到MASK_CHANNEL_READ的上下文,即:ServerBootstrapAcceptor。
@Override
@SuppressWarnings("unchecked")
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 此msg其实就是NioSocketChannel
final Channel child = (Channel) msg;
// 此childHandler 其实就是 BootstrapInitializerHandler
// 赋值的时机是在TcpServerBind的bind方法中
child.pipeline().addLast(childHandler);
setChannelOptions(child, childOptions, logger);
setAttributes(child, childAttrs);
try {
// 开启NioSocketChannel的注册流程,
// 此流程通NioServerSocketChannel流程一样
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);
}
}
当执行到NioSocketChannel的register0
时,由此方法下的pipeline.invokeHandlerAddedIfNeeded();
开启NettyReactor的自定义的Handler:BootstrapInitializerHandler的初始化流程
。
@Override
protected void initChannel(Channel ch) {
if (pipeline != null) {
for (PipelineConfiguration pipelineConfiguration : pipeline) {
// Http1Initializer的accept方法
// 再向此channel的pipeline中添加两个Handler
// 一个是HttpServerCodec
// 一个是HttpTrafficHandler,在这个handler添加addLast过程中
// 通过ctx.read()完成此channel的状态为由0【初始状态】变1【读状态】的操作
pipelineConfiguration.consumer.accept(listener, ch);
}
}
// 添加ChannelOperationsHandler
ChannelOperations.addReactiveBridge(ch, opsFactory, listener);
if (log.isDebugEnabled()) {
log.debug(format(ch, "Initialized pipeline {}"), ch.pipeline().toString());
}
}
当完成对BootstrapInitializerHandler的初始化,在此channel的pipeline中删除其上下文:
接着完成safeSetSuccess()和fireChannelRegistered()这两个阶段,触发通道的激活pipeline.fireChannelActive();
:
@Override