Netty源码分析(七):初识ChannelPipeline
ChannelPipeline
单看名称就可以知道Channel
的管道。本篇将结合它的默认实现类DefaultChannelPipeline
来对它做一个简单的介绍。
示例图
上图是官方提供的ChannelPipeline
的事例图。IO请求经由ChannelOutboundHandler
中ChannelOutboundHandler
处理之后写出到服务端,服务接收到读入后,由ChannelInboundHandler
依次处理。
下面来看下DefaultChannelPipeline
的类图:
DefaultChannelPipeline
实现了ChannelPipeline
接口,而ChannelPipeline
又继承了ChannelInboundInvoker
、ChannelOutboundInvoker
和Iterable
。
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
添加成功后,再调用ChannelHandler
的handlerAdded
方法。其它的添加方式和addFirst
类似。
事件触发
以fireChannelActive
方法为例:
public final ChannelPipeline fireChannelActive() {
AbstractChannelHandlerContext.invokeChannelActive(head);
return this;
}
从HeadContext
的head开始,依次触发下一个ChannelHandler
的channelActive
方法。
本篇简单介绍了ChannelPipeline
的相关概念,当ChannelHandler
介绍完后,再具体介绍ChannelPipeline
中的HeadContext
和TailContext
。
文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。
本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!
Netty源码分析(七):初识ChannelPipeline的更多相关文章
- Netty源码分析第7章(编码器和写数据)---->第3节: 写buffer队列
Netty源码分析七章: 编码器和写数据 第三节: 写buffer队列 之前的小节我们介绍过, writeAndFlush方法其实最终会调用write和flush方法 write方法最终会传递到hea ...
- Netty源码分析 (七)----- read过程 源码分析
在上一篇文章中,我们分析了processSelectedKey这个方法中的accept过程,本文将分析一下work线程中的read过程. private static void processSele ...
- Netty 源码分析——ChannelPipeline
Netty 源码分析--ChannelPipeline 通过前面的两章我们分析了客户端和服务端的流程代码,其中在初始化 Channel 的时候一定会看到一个 ChannelPipeline.所以在 N ...
- Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾
Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...
- netty源码分析之二:accept请求
我在前面说过了server的启动,差不多可以看到netty nio主要的东西包括了:nioEventLoop,nioMessageUnsafe,channelPipeline,channelHandl ...
- Netty源码分析(前言, 概述及目录)
Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...
- Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化
Netty源码分析第一章:Netty启动流程 第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...
- Netty源码分析第2章(NioEventLoop)---->第7节: 处理IO事件
Netty源码分析第二章: NioEventLoop 第七节:处理IO事件 上一小节我们了解了执行select()操作的相关逻辑, 这一小节我们继续学习select()之后, 轮询到io事件的相关 ...
- Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建
Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...
- Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建
Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...
随机推荐
- Java中String的设计
String应用简介 前言 String字符串在Java应用中使用非常频繁,只有理解了它在虚拟机中的实现机制,才能写出健壮的应用,本文使用的JDK版本为1.8.0_111. 常量池 Java代码被编译 ...
- 使用git连接到Github
直奔主题,使用git连接到Github步骤如下: 1. 安装git yum install git 或者 sudo get-apt install git git-core 2. 全局配置 git c ...
- css3立体旋转菜单
css3立体旋转菜单,css3,3D,立体旋转,立体菜单,菜单导航,css3立体旋转菜单是一款纯css3实现的三维立体旋转导航菜单. 源码下载页:http://www.huiyi8.com/sc/71 ...
- 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配置 首先解 ...
- 集训Day6
今天的图论题略多 但好像都是noip题 bzoj3624 有一个图,边是黑色或者白色,求一个生成树满足恰好有k条白边 贪心 我们把最小生成树上的白边叫做“富家子弟”,把不在树上的叫“贫下中农” 很明显 ...
- HihoCoder1670 : 比赛日程安排([Offer收割]编程练习赛41)(模拟)
描述 H国编程联赛中有N只队伍,编号1~N. 他们计划在2018年一共进行M场一(队)对一(队)的比赛. 为了让参赛队员能得到充分的休息,联赛组委会决定:每支队伍连续两场比赛之间至少间隔一天.也就是如 ...
- k8s-部署WEB-UI(dashboard)
[root@k8s-master dashboard]# pwd/usr/local/src/kubernetes/cluster/addons/dashboard [root@k8s-master ...
- Django | 执行项目下指定的脚本
1 描述 有时候会碰到这样的场景,对于一些业务升级,我需要把数据库数据做些处理,同时又想以 Django 项目的环境变量执行脚本,这个时候使用 python 脚本是再适合不过的手段了. 2 使用自带的 ...
- python爬虫知识点详解
python爬虫知识点总结(一)库的安装 python爬虫知识点总结(二)爬虫的基本原理 python爬虫知识点总结(三)urllib库详解 python爬虫知识点总结(四)Requests库的基本使 ...
- 重学JAVA基础(五):面向对象
1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...