ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

netty源码之业务逻辑处理

2021-07-27 21:04:24  阅读:161  来源: 互联网

标签:netty 逻辑 handler allocHandle pipeline 源码 byteBuf config final


目录

前言

流程

1、业务逻辑的入口,read

2、从pipeline的链表上依次执行


前言

 

红色的部分就是我们这次分析的核心

img

pipeline , 本质上是一个双向的链接,请注意是双向 , 它有head、tail , 中间有很多Context , 每个context 包含了需要执行的handler ,我们可以正向或者反向的查找下一个要执行的handler。

img

流程

1、业务逻辑的入口,read

业务逻辑的切入点,可以很明确的确认是在读数据的流程中的,所以我们打开NioEventLoop对象。

在这个读的逻辑里 , 处理数据是从这里开始的 pipeline.fireChannelRead(byteBuf).

    @Override
    public final void read() {
        final ChannelConfig config = config();
        if (shouldBreakReadReady(config)) {
            clearReadPending();
            return;
        }
        final ChannelPipeline pipeline = pipeline();
        // 内存分配器
        final ByteBufAllocator allocator = config.getAllocator();
        // 接收数据测handler
        final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
        allocHandle.reset(config);
​
        ByteBuf byteBuf = null;
        boolean close = false;
        try {
            do {
                // 分配内存是自适应的
                byteBuf = allocHandle.allocate(allocator);
                // 开始读取数据
                allocHandle.lastBytesRead(doReadBytes(byteBuf));
                if (allocHandle.lastBytesRead() <= 0) {// 读取失败
                    // nothing was read. release the buffer.
                    byteBuf.release();
                    byteBuf = null;
                    close = allocHandle.lastBytesRead() < 0;
                    if (close) {
                        // There is nothing left to read as we received an EOF.
                        readPending = false;
                    }
                    break;
                }
​
                allocHandle.incMessagesRead(1);//读取一次数据
                readPending = false;
                pipeline.fireChannelRead(byteBuf);// 将读到的数据传递出去
                byteBuf = null;
            } while (allocHandle.continueReading());//继续读取
​
            // 通过当前
            allocHandle.readComplete();//计算下一次的需要分配的空间
            pipeline.fireChannelReadComplete();// 将完成读取的事件传递出去
​
            if (close) {
                closeOnRead(pipeline);
            }
        } catch (Throwable t) {
            handleReadException(pipeline, byteBuf, t, close, allocHandle);
        } finally {
            // Check if there is a readPending which was not processed yet.
            // This could be for two reasons:
            // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method
            // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method
            //
            // See https://github.com/netty/netty/issues/2254
            if (!readPending && !config.isAutoRead()) {
                removeReadOp();
            }
        }
    }
}

2、从pipeline的链表上依次执行

img

pipeline上的节点 是handlerContext , 所以执行的过程就是pipeline上找到context节点 , 然后处理节点内的handler

img

最终会走到我们自定义的handler里

img

标签:netty,逻辑,handler,allocHandle,pipeline,源码,byteBuf,config,final
来源: https://blog.csdn.net/u012391423/article/details/119153086

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有