ChannelPipeline类似于一个管道,管道中存放的是一系列对读取数据进行业务操作的ChannelHandler。

1、ChannelPipeline的结构图:

在之前的博客【Netty源码学习】入门示例我们看到了如下的代码:

future.channel().writeAndFlush("Hello Netty Server ,I am a common client");  

其实就是Client向Server发送数据,其具体实现是在AbstractChannel类中

@Override
    public ChannelFuture writeAndFlush(Object msg) {
        return pipeline.writeAndFlush(msg);
    }

上面这段代码出现了我们这篇博客要分析的类DefaultChannelPipeline,其是ChannelPipeline的实现类。DefaultChannelPipeline中writeAndFlush(msg)的实现如下:

@Override
    public final ChannelFuture writeAndFlush(Object msg) {
        return tail.writeAndFlush(msg);
    }

tail对象的定义如下final AbstractChannelHandlerContext tail,接口为ChannelHandlerContext我们会接下来进行分析,其进一步封装了数据读写操作。现在看好像DefaultChannelPipeline的使命已经结束了,发送数据的操作在AbstractChannelHandlerContext中实现。

接下来我们详细介绍一下DefaultChannelPipeline,一开始我们说它是一个管道,是因为他的名称是pipe,其实现在看来他更像一个链表(其实是一个双向循环链表),队列的单位是AbstractChannelHandlerContext,因为其定义了两个变量。

final AbstractChannelHandlerContext head;
    final AbstractChannelHandlerContext tail;

head为链表的头,tail为链表的尾,接下来的很多操作都与head和tail相关的。添加ChannelHandler操作。

@Override
    public final ChannelPipeline addFirst(String name, ChannelHandler handler) {
        return addFirst(null, name, handler);
    }

    @Override
    public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            checkMultiplicity(handler);
            name = filterName(name, handler);

            newCtx = newContext(group, name, handler);

            addFirst0(newCtx);

            // If the registered is false it means that the channel was not registered on an eventloop yet.
            // In this case we add the context to the pipeline and add a task that will call
            // ChannelHandler.handlerAdded(...) once the channel is registered.
            if (!registered) {
                newCtx.setAddPending();
                callHandlerCallbackLater(newCtx, true);
                return this;
            }

            EventExecutor executor = newCtx.executor();
            if (!executor.inEventLoop()) {
                newCtx.setAddPending();
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        callHandlerAdded0(newCtx);
                    }
                });
                return this;
            }
        }
        callHandlerAdded0(newCtx);
        return this;
    }

    private void addFirst0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext nextCtx = head.next;
        newCtx.prev = head;
        newCtx.next = nextCtx;
        head.next = newCtx;
        nextCtx.prev = newCtx;
    }

在addFirst0中我们可以清晰的看到,创建双向循环对列,对列的基本单位是AbstractChannelHanndlerContext。ChannelPipeline继承ChannelInboundInvoker和ChannelOutboundInvoker,它既是一个inboundinvoke,又是一个outboundinvoke,同时也是ChannelChandler的管理者,提供了很多对handler进行的操作。

我们介绍一下channelActive操作channelActive函数

@Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.fireChannelActive();

            readIfIsAutoRead();
        }

其具体实现在我们继承的ChannelHandlerContext类中,比如我们入门教程中的ClientHandler中

@Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("HelloWorldClientHandler Active");
    }  

由于ChannelHandlerContext是实现数据读写的具体操作类,DefaultChannelPipeline实现了一个ChannelHandlerContext的双向链表,ChannelHandlerContext中封装了我们对消息数据的具体操作比如ClientHandler打印数据,因此DefaultChannelPipeplie的双向链表就是对数据的各种操作,所以在很多地方都会看到pipeline的身影。

【Netty源码学习】ChannelPipeline(一)的更多相关文章

  1. 【Netty源码学习】DefaultChannelPipeline(三)

    上一篇博客中[Netty源码学习]ChannelPipeline(二)我们介绍了接口ChannelPipeline的提供的方法,接下来我们分析一下其实现类DefaultChannelPipeline具 ...

  2. Netty 源码学习——EventLoop

    Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...

  3. Netty 源码学习——客户端流程分析

    Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...

  4. Netty源码学习系列之4-ServerBootstrap的bind方法

    前言 今天研究ServerBootstrap的bind方法,该方法可以说是netty的重中之重.核心中的核心.前两节的NioEventLoopGroup和ServerBootstrap的初始化就是为b ...

  5. 【Netty源码学习】ServerBootStrap

    上一篇博客[Netty源码学习]BootStrap中我们介绍了客户端使用的启动服务,接下来我们介绍一下服务端使用的启动服务. 总体来说ServerBootStrap有两个主要功能: (1)调用父类Ab ...

  6. Netty 源码分析——ChannelPipeline

    Netty 源码分析--ChannelPipeline 通过前面的两章我们分析了客户端和服务端的流程代码,其中在初始化 Channel 的时候一定会看到一个 ChannelPipeline.所以在 N ...

  7. Netty源码解析 -- ChannelPipeline机制与读写过程

    本文继续阅读Netty源码,解析ChannelPipeline事件传播原理,以及Netty读写过程. 源码分析基于Netty 4.1 ChannelPipeline Netty中的ChannelPip ...

  8. 【Netty源码学习】EventLoopGroup

    在上一篇博客[Netty源码解析]入门示例中我们介绍了一个Netty入门的示例代码,接下来的博客我们会分析一下整个demo工程运行过程的运行机制. 无论在Netty应用的客户端还是服务端都首先会初始化 ...

  9. Netty源码学习(六)ChannelPipeline

    0. ChannelPipeline简介 ChannelPipeline = Channel + Pipeline,也就是说首先它与Channel绑定,然后它是起到类似于管道的作用:字节流在Chann ...

随机推荐

  1. ●BZOJ 3529 [Sdoi2014]数表

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...

  2. bzoj4447[Scoi2015]小凸解密码

    4447: [Scoi2015]小凸解密码 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 150  Solved: 58[Submit][Status ...

  3. hdu5651 xiaoxin juju needs help(逆元)

    xiaoxin juju needs help  Accepts: 150  Submissions: 966  Time Limit: 2000/1000 MS (Java/Others)  Mem ...

  4. python 字典实现简单购物车

    # -*- coding: utf-8 -*-#总金额asset_all=0i1=input('请输入总资产:')asset_all=int(i1)#商品列表goods=[ {'name':'电脑', ...

  5. 离线合成联想到的--canvas合成水印

    前段时间做了功能模块:用户设置自定义勋章: 实现方式:前端把用户设置的昵称传到后台,后台根据不同用户等级,使用离线合成技术合成不同的勋章返回到前端: 方案算是实现了,但是有点坑就是,后台的离线合成没有 ...

  6. 导出数据子集:带where条件的exp导出

    举个例子:用select * from all_objects创建了一张表T.想要导出object_id小于5000的所有行.(1)windows下: exp userid=cms0929/cms09 ...

  7. python学习之路网络编程篇(第五篇)-续篇

    Python堡垒机实现之基础知识 一般的堡垒机必须要具备以下5个基本功能: 1.权限控制 2.执行命令 3.上传下载文件 4.远程登录 5.记录操作 权限控制 说明:根据不同的登录用户分配不同的可管理 ...

  8. Tomcat安装及问题排查方法

    简介: Apache Jakarta的开源项目 JSP/Servlet容器 安装: 1.1进入 Tomcat 官方下载地址 选择合适版本下载,并解压到本地. (备注)Tomcat 8.5 要求 JDK ...

  9. ACM Super Jumping! Jumping! Jumping!

    Nowadays, a kind of chess game called "Super Jumping! Jumping! Jumping!" is very popular i ...

  10. Android Studio精彩案例(五)《JSMS短信验证码功能实现》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用.那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能 ...