Netty源码学习(4)--新连接接入

NioEventLoop中已经知道,当服务端绑启动之后,服务端的channel已经注册到boos reactor线程中,reactor不断检测有新的事件,直到检测出有accept事件发生。当程序进入processSelectedKey方法中时,判断条件SelectionKey.OP_READ 表示boos reactor线程已经轮询到 SelectionKey.OP_ACCEPT 事件,说明有新的连接进入,此时将调用channel的 unsafe来进行实际的操作。如下图:

Netty源码学习(4)--新连接接入_第1张图片

channel底层都会有一个与unsafe绑定,每种类型的channel实际的操作都由unsafe来实现

服务端对应的channel的unsafe是 NioMessageUnsafe

入到它的read方法,进入新连接处理的第二步

注册到reactor线程:

NioMessageUnsafe.java

Netty源码学习(4)--新连接接入_第2张图片
Netty源码学习(4)--新连接接入_第3张图片

assert eventLoop().inEventLoop();

断言确定该read方法必须是reactor线程调用,

final ChannelPipeline pipeline = pipeline();

然后拿到channel对应的pipeline

int localRead = doReadMessages(readBuf);

调用 doReadMessages 方法不断地读取消息,用 readBuf 作为容器

然后调用 pipeline.fireChannelRead(),将每条新连接经过一层服务端channel的洗礼

之后清理容器,触发 pipeline.fireChannelReadComplete()



1. doReadMessages()

NioServerSocketChannel继承AbstractNioMessageChannel,实现了AbstractNioMessageChannel中的doReadMessages()方法:

Netty源码学习(4)--新连接接入_第4张图片

netty调用jdk底层nio的边界 javaChannel().accept();,由于netty中reactor线程第一步就扫描到有accept事件发生,因此,这里的accept方法是立即返回的,返回jdk底层nio创建的一条channel;

buf.add(new NioSocketChannel(this, ch));

netty将jdk的 SocketChannel 封装成自定义的 NioSocketChannel,加入到list里面,这样外层就可以遍历该list,做后续处理



2.pipeline.fireChannelRead(NioSocketChannel)

简单介绍一下pipeline这个组件:

在netty的各种类型的channel中,都会包含一个pipeline,字面意思是管道,我们可以理解为一条流水线工艺,流水线工艺有起点,有结束,中间还有各种各样的流水线关卡,一件物品,在流水线起点开始处理,经过各个流水线关卡的加工,最终到流水线结束

对应到netty里面,流水线的开始就是HeadContxt,流水线的结束就是TailConext,HeadContxt中调用Unsafe做具体的操作,TailConext中用于向用户抛出pipeline中未处理异常以及对未处理消息的警告

pipeline.fireChannelRead(NioSocketChannel); 最终通过head->unsafe->ServerBootstrapAcceptor的调用链,调用到这里的 ServerBootstrapAcceptor 的channelRead方法:

Netty源码学习(4)--新连接接入_第5张图片

你可能感兴趣的:(Netty源码学习(4)--新连接接入)