ChannelPipeline单看名称就可以知道Channel的管道。本篇将结合它的默认实现类DefaultChannelPipeline来对它做一个简单的介绍。

示例图



上图是官方提供的ChannelPipeline的事例图。IO请求经由ChannelOutboundHandlerChannelOutboundHandler处理之后写出到服务端,服务接收到读入后,由ChannelInboundHandler依次处理。

下面来看下DefaultChannelPipeline的类图:



DefaultChannelPipeline实现了ChannelPipeline接口,而ChannelPipeline又继承了ChannelInboundInvokerChannelOutboundInvokerIterable

ChannelInboundInvoker:发起对ChannelPipeline中下一个ChannelInboundHandler的方法的调用。

ChannelOutboundInvoker:发起对ChannelPipeline中下一个ChannelOutboundHandler的方法的调用。

Iterable:可遍历ChannelPipeline中的ChannelHandler

NioEventLoop继承自SingleThreadEventLoop,而SingleThreadEventLoop又继承自SingleThreadEventExecutor

SingleThreadEventExecutor内部持有一个Thread对象,是Netty多线程的基础。

可以认为, 一个NioEventLoop与一个特定的线程进行了绑定,并且在其生命周期内,绑定的线程都不会再改变。

DefaultChannelPipeline

DefaultChannelPipeline的主要工作就是对ChannelHandler的管理,包括ChannelHandler的增减,事件的触发等。

ChannelHandler的增减

addFirst方法为例:

    public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized (this) {
// 检查handler是否可以共享
checkMultiplicity(handler);
// 给AbstractChannelHandlerContext起个独立的名字
name = filterName(name, handler);
// 创建DefaultChannelHandlerContext
newCtx = newContext(group, name, handler);
// 执行实际的添加操作
addFirst0(newCtx);
// channel尚未注册到eventloop
if (!registered) {
// 设置newCtx的状态为ADD_PENDING
newCtx.setAddPending();
// 设置过一会回调ChannelHandler的handlerAdded方法
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;
}

addFirst方法先检查添加的ChannelHandler是否可以共享(判断共享的方法是对于每个channel当前ChannelHandler是否需要不同的状态),再创建ChannelHandler的上下文关系,使ChannelHandler以链表方式存在于ChannelPipeline中。当ChannelHandler添加成功后,再调用ChannelHandlerhandlerAdded方法。其它的添加方式和addFirst类似。

事件触发

fireChannelActive方法为例:

    public final ChannelPipeline fireChannelActive() {
AbstractChannelHandlerContext.invokeChannelActive(head);
return this;
}

HeadContext的head开始,依次触发下一个ChannelHandlerchannelActive方法。

本篇简单介绍了ChannelPipeline的相关概念,当ChannelHandler介绍完后,再具体介绍ChannelPipeline中的HeadContextTailContext

文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。


本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!

Netty源码分析(七):初识ChannelPipeline的更多相关文章

  1. Netty源码分析第7章(编码器和写数据)---->第3节: 写buffer队列

    Netty源码分析七章: 编码器和写数据 第三节: 写buffer队列 之前的小节我们介绍过, writeAndFlush方法其实最终会调用write和flush方法 write方法最终会传递到hea ...

  2. Netty源码分析 (七)----- read过程 源码分析

    在上一篇文章中,我们分析了processSelectedKey这个方法中的accept过程,本文将分析一下work线程中的read过程. private static void processSele ...

  3. Netty 源码分析——ChannelPipeline

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

  4. Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾

    Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...

  5. netty源码分析之二:accept请求

    我在前面说过了server的启动,差不多可以看到netty nio主要的东西包括了:nioEventLoop,nioMessageUnsafe,channelPipeline,channelHandl ...

  6. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  7. Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

    Netty源码分析第一章:Netty启动流程   第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...

  8. Netty源码分析第2章(NioEventLoop)---->第7节: 处理IO事件

    Netty源码分析第二章: NioEventLoop   第七节:处理IO事件 上一小节我们了解了执行select()操作的相关逻辑, 这一小节我们继续学习select()之后, 轮询到io事件的相关 ...

  9. Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建

    Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...

  10. Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建

    Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...

随机推荐

  1. Java中String的设计

    String应用简介 前言 String字符串在Java应用中使用非常频繁,只有理解了它在虚拟机中的实现机制,才能写出健壮的应用,本文使用的JDK版本为1.8.0_111. 常量池 Java代码被编译 ...

  2. 使用git连接到Github

    直奔主题,使用git连接到Github步骤如下: 1. 安装git yum install git 或者 sudo get-apt install git git-core 2. 全局配置 git c ...

  3. css3立体旋转菜单

    css3立体旋转菜单,css3,3D,立体旋转,立体菜单,菜单导航,css3立体旋转菜单是一款纯css3实现的三维立体旋转导航菜单. 源码下载页:http://www.huiyi8.com/sc/71 ...

  4. arm-linux-gcc4.4.3编译busybox-1.25.0

    系统环境: 1.操作系统:Ubuntu16.04 2.交叉编译工具链:arm-linux-gcc4.4.3 3.busybox源码包:busybox-1.25.0 一.修改Makefile配置 首先解 ...

  5. 集训Day6

    今天的图论题略多 但好像都是noip题 bzoj3624 有一个图,边是黑色或者白色,求一个生成树满足恰好有k条白边 贪心 我们把最小生成树上的白边叫做“富家子弟”,把不在树上的叫“贫下中农” 很明显 ...

  6. HihoCoder1670 : 比赛日程安排([Offer收割]编程练习赛41)(模拟)

    描述 H国编程联赛中有N只队伍,编号1~N. 他们计划在2018年一共进行M场一(队)对一(队)的比赛. 为了让参赛队员能得到充分的休息,联赛组委会决定:每支队伍连续两场比赛之间至少间隔一天.也就是如 ...

  7. k8s-部署WEB-UI(dashboard)

    [root@k8s-master dashboard]# pwd/usr/local/src/kubernetes/cluster/addons/dashboard [root@k8s-master ...

  8. Django | 执行项目下指定的脚本

    1 描述 有时候会碰到这样的场景,对于一些业务升级,我需要把数据库数据做些处理,同时又想以 Django 项目的环境变量执行脚本,这个时候使用 python 脚本是再适合不过的手段了. 2 使用自带的 ...

  9. python爬虫知识点详解

    python爬虫知识点总结(一)库的安装 python爬虫知识点总结(二)爬虫的基本原理 python爬虫知识点总结(三)urllib库详解 python爬虫知识点总结(四)Requests库的基本使 ...

  10. 重学JAVA基础(五):面向对象

    1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...