美文网首页
Netty源码学习(4)--新连接接入

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

作者: 未名枯草 | 来源:发表于2018-01-15 14:43 被阅读31次

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

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

    服务端对应的channel的unsafe是 NioMessageUnsafe

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

    注册到reactor线程:

    NioMessageUnsafe.java

    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调用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)--新连接接入

          本文链接:https://www.haomeiwen.com/subject/bqvznxtx.html