Netty 的 inbound 与 outbound, 以及 InboundHandler 的 channelInactive 与 OutboundHandler 的 close
先看一个例子.
有一个简单 Server
public class SimpleServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_SNDBUF, 1024 * 1024)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new SimpleDuplex1());
ch.pipeline().addLast(new SimpleDuplex2());
ch.pipeline().addLast(new SimpleServerHandler());
}
});
b.bind(8090).sync().channel().closeFuture().sync();
}
}
Handler 详情如下
public class SimpleDuplex1 extends ChannelDuplexHandler { @Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("---- write 1 ----");
super.write(ctx, msg, promise);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("---- read 1 ----");
super.channelRead(ctx, msg);
}
} public class SimpleDuplex2 extends ChannelDuplexHandler { @Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("---- write 2 ----");
super.write(ctx, msg, promise);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("---- read 2 ----");
super.channelRead(ctx, msg);
}
}
public class SimpleServerHandler extends ChannelDuplexHandler { @Override
public void channelRead(ChannelHandlerContext ctx, final Object msg) throws Exception {
ctx.channel().writeAndFlush(ByteBufAllocator.DEFAULT.buffer().writeBytes("OK".getBytes())).addListener(ChannelFutureListener.CLOSE);
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("----- INACTIVE -----");
super.channelInactive(ctx);
} @Override
public void close(ChannelHandlerContext ctx, ChannelPromise future) throws Exception {
System.out.println("----- CLOSE -----");
super.close(ctx, future);
}
}
启动 Server 以后, 使用 telnet 发送数据查看执行结果
---- read 1 ----
---- read 2 ----
成功
---- write 2 ----
---- write 1 ----
----- CLOSE -----
----- INACTIVE -----
1. 先来看看执行顺序, 可见, inbound 的顺序是跟 add 顺序一致的, 而 outbound 的顺序是跟 add 顺序相反的
以及, read 的 IO 触发顺序是 "socketChannel.read() -> 顺序 handler -> TailContext.channelRead().releaseMsg"
而 write 的 IO 触发顺序是 "逆序 handler -> HeadContext.socketChannel.write()"
也就是说 read 是先触发 socket 的 read IO 时间, 再进入 handler, 而如果我们最后一个 handler 未能完全处理消息, 调用了 super.channelRead, 则会进入 TailContext. 此时TailContext 会打出 debug 消息告诉你消息进入了最后一个 Handler 而未被处理. 因为一般来讲都应该在自己的 handler 里把消息处理掉. 而不是让他进入到默认 handler 里.
而对于 write 来说, 则是先进入自定义 handler, 最后在进入 HeadContext 触发 IO 时间
2. 再来说说 close 与 channelInactive
前面说到了. Outbound 的顺序是最后才执行到 HeadContext 来执行实际的 IO 操作, close 也是一样, 当你调用 channle.close 的时候, 先会经过你的 handler . 最后调用 HeadContext.socketChannel.close(). 所以, 在我们的 Handler 中, 先会打印 "---- CLOSE ----" 然后再调用实际的 socketChannel.close. 最后, 当 close 成功时, 触发 ChannelInactive 时间.
所以说 close 与 channelInactive 的关系是 close 是主动关闭 channel 的动作, 而 channelInactive 是关闭成功后收到通知的事件.
Netty 的 inbound 与 outbound, 以及 InboundHandler 的 channelInactive 与 OutboundHandler 的 close的更多相关文章
- pcie inbound、outbound及EP、RC间的互相訪问
Inbound:PCI域訪问存储器域 Outbound:存储器域訪问PCI域 RC訪问EP: RC存储器域->outbound->RC PCI域->EP PCI域->inbou ...
- netty中的Channel、ChannelPipeline
一.Channel与ChannelPipeline关系 每一个新创建的 Channel 都将会被分配一个新的 ChannelPipeline.这项关联是永久性 的:Channel 既不能附加另外一个 ...
- netty中的引导Bootstrap客户端
一.Bootstrap Bootstrap 是 Netty 提供的一个便利的工厂类, 我们可以通过它来完成 Netty 的客户端或服务器端的 Netty 初始化.下面我以 Netty 源码例子中的 E ...
- Netty版本升级血泪史之线程篇
1. 背景 1.1. Netty 3.X系列版本现状 根据对Netty社区部分用户的调查,结合Netty在其它开源项目中的使用情况,我们可以看出目前Netty商用的主流版本集中在3.X和4.X上,其中 ...
- netty源码学习
概述 Netty is an asynchronous event-driven network application framework for rapid development of main ...
- Pipeline inbound(netty源码7)
netty源码死磕7 Pipeline 入站流程详解 1. Pipeline的入站流程 在讲解入站处理流程前,先脑补和铺垫一下两个知识点: (1)如何向Pipeline添加一个Handler节点 ( ...
- 【Netty】(8)---理解ChannelPipeline
ChannelPipeline ChannelPipeline不是单独存在,它肯定会和Channel.ChannelHandler.ChannelHandlerContext关联在一起,所以有关概念这 ...
- Netty 核心组件 Pipeline 源码分析(一)之剖析 pipeline 三巨头
目录大纲: 前言 ChannelPipeline | ChannelHandler | ChannelHandlerContext 三巨头介绍 三巨头编织过程(创建过程) ChannelPipelin ...
- Netty源码分析第4章(pipeline)---->第1节: pipeline的创建
Netty源码分析第四章: pipeline 概述: pipeline, 顾名思义, 就是管道的意思, 在netty中, 事件在pipeline中传输, 用户可以中断事件, 添加自己的事件处理逻辑, ...
随机推荐
- php使用ajax导出CSV或者EXCEl(thinkphp)方法
首先我强烈推荐看到这篇文章的你将导出文件设置为csv格式的文件 实际测试导出csv文件的速度是excel文件的10几倍左右 首先我先介绍csv文件的导出的方法: 如果你单纯是在数据导出界面上通过用户点 ...
- JAVA学习笔记(33-53)
33:java中的多维数组,以二位为例: 创建方法:int[][] a = new int[2][3]; 建立一个5*5的数组. 或者下面的建立方法也可以: int[][] c = { {1, 2, ...
- IP转换hash以及返回
InetAddress address = InetAddress.getByName("127.0.0.1"); System.out.println(address); int ...
- GIS基本概念
简介 WKT(Well-known text)是开放地理空间联盟OGC(Open GIS Consortium )制定的一种文本标记语言,用于表示矢量几何对象.空间参照系统及空间参照系统之间的转换. ...
- 实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1
本片博客为实验楼的训练营课程深入学习<C++ Primer第五版>的实验报告和学习笔记. 原课程地址为:https://www.shiyanlou.com/courses/405# 原文出 ...
- Linux和windows之间通过scp复制文件
Windows是不支持ssh协议的 需要安装WinSSHD 安装以及设置过程如下: BvSshServer(原名winsshd)官方下载页在这里:https://www.bitvise.com/dow ...
- LR自定义函数以及调用
2.2.自定义函数以及调用 2.2.1.虚拟用户编程,使用C# 语言DLL 在VS中建立DLL类库项目,编写函数时使用public声明:实现函数后编译生成DLL: 在LR中建立 .Net Vuser脚 ...
- Matlab Map
http://blog.csdn.net/yuzhiyuxia/article/details/7305225 >> weekmap = containers.Map({'Monday', ...
- 智慧城市的【Auth】登录对象
从Auth对象看前端:1.将与Auth对象相关的功能分离出来.所含的内容包括:[个人中心相关信息的显示,注册,登录,忘记密码,修改密码,个人信息修改]. 2.从“我的”页面开始,显示使用哪儿的数据,需 ...
- strstr函数
原型:char * strstr( char *haystack, char *needle ) 用法:#include <string.h> 功能:在haystack中寻找needle ...