Netty中ChannelHandler的生命周期
在使用Netty进行网络编程的时候,通常需要在网络连接的不同阶段进行相应的操作,比如在连接建立时,客户端向服务端发起认证,在接收到数据时对数据内容进行解析等等。那么,连接的不同阶段在netty中如何表示呢? 这便是本文讨论的内容,Netty中ChannelHandller的生命周期。
首先我们先分析小网络连接的生命周期,连接建立 ---> 数据交互 ---> 连接断开,在数据交互阶段,包括从连接中读取数据和向连接中写入数据。知道了连接的生命周期,就可以按图索骥的在各个阶段进行想要的操作。而在Netty中,网络连接的不同生命周期都可以通过回调的方式来绑定相应的逻辑,这个回调接口就是ChannelHandler,这里主要我们以ChannelInboundHandler为例进行分析。在ChannelInboundHandler中定义了如下和生命周期相关的接口:
- channelRegistered
- channelUnregistered
- channelActive
- channelInactive
- channelRead
- channelReadComplete
加上在父类``中定义的两个:
- handlerAdded
- handlerRemoved
这些回调接口的调用书序是什么呢?我们通过写一个LifeCycleHandler来看下ChannelInboundHandler的生命周期的顺序。
public class LifeCycleInBoundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRegistered(ChannelHandlerContext ctx)
throws Exception {
out.println("channelRegistered: channel注册到NioEventLoop");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx)
throws Exception {
out.println("channelUnregistered: channel取消和NioEventLoop的绑定");
super.channelUnregistered(ctx);
}
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
out.println("channelActive: channel准备就绪");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx)
throws Exception {
out.println("channelInactive: channel被关闭");
super.channelInactive(ctx);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
out.println("channelRead: channel中有可读的数据" );
super.channelRead(ctx, msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
throws Exception {
out.println("channelReadComplete: channel读数据完成");
super.channelReadComplete(ctx);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx)
throws Exception {
out.println("handlerAdded: handler被添加到channel的pipeline");
super.handlerAdded(ctx);
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx)
throws Exception {
out.println("handlerRemoved: handler从channel的pipeline中移除");
super.handlerRemoved(ctx);
}
}
启动服务器和Client,连接成功后,断开client的连接,Server端输出结果如下:
handlerAdded: handler被添加到channel的pipeline
channelRegistered: channel注册到NioEventLoop
channelActive: channel准备就绪
channelRead: channel中有可读的数据
channelReadComplete: channel读数据完成
channelReadComplete: channel读数据完成
channelInactive: channel被关闭
channelUnregistered: channel取消和NioEventLoop的绑定
handlerRemoved: handler从channel的pipeline中移除
从上面结果可以知道,从连接建立到连接断开,handler的生命周期回调接口调用顺序如下:
handlerAdded -> channelRegistered
-> channelActive -> channelRead -> channelReadComplete
-> channelInactive -> channelUnRegistered -> handlerRemoved
下面具体说下每个回调的具体含义:
- handlerAdded: 新建立的连接会按照初始化策略,把handler添加到该channel的pipeline里面,也就是channel.pipeline.addLast(new LifeCycleInBoundHandler)执行完成后的回调;
- channelRegistered: 当该连接分配到具体的worker线程后,该回调会被调用。
- channelActive:channel的准备工作已经完成,所有的pipeline添加完成,并分配到具体的线上上,说明该channel准备就绪,可以使用了。
- channelRead:客户端向服务端发来数据,每次都会回调此方法,表示有数据可读;
- channelReadComplete:服务端每次读完一次完整的数据之后,回调该方法,表示数据读取完毕;
- channelInactive:当连接断开时,该回调会被调用,说明这时候底层的TCP连接已经被断开了。
- channelUnREgistered: 对应channelRegistered,当连接关闭后,释放绑定的workder线程;
- handlerRemoved: 对应handlerAdded,将handler从该channel的pipeline移除后的回调方法。

Netty中ChannelHandler的生命周期的更多相关文章
- spring IOC 容器中 Bean 的生命周期
IOC 容器中 Bean 的生命周期: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.调用 Bean 后置处理器接口(BeanPostPr ...
- (spring-第1回【IoC基础篇】)Spring容器中Bean的生命周期
日出日落,春去秋来,花随流水,北雁南飞,世间万物皆有生死轮回.从调用XML中的Bean配置信息,到应用到具体实例中,再到销毁,Bean也有属于它的生命周期. 人类大脑对图像的认知能力永远高于文字,因此 ...
- JAVA面试题:Spring中bean的生命周期
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...
- Android应用程序中Activity的生命周期
Android应用程序中Activity的生命周期 对于Android来说Activity的生命周期是非常的重要,尤其是对于新学者来说,只有充分了解了Activity的生命周期,才能写出优良用户体验的 ...
- Spring IOC容器中Bean的生命周期
1.IOC容器中Bean的生命周期 构造器函数 设置属性 初始化函数(在Bean配置中 init-method) 使用Bean 结束时关闭容器(在Bean中配置destroy-method) 2.Be ...
- 深入理解Spring中bean的生命周期
[Spring中bean的生命周期] bean的生命周期 1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例 ...
- Spring中Bean的生命周期及其扩展点
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6106456.html Spring中Bean的管理是其最基本的功能,根据下面的图来了解Spr ...
- 简:Spring中Bean的生命周期及代码示例
(重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...
- spring BeanFactory及ApplicationContext中Bean的生命周期
spring bean 的生命周期 spring BeanFactory及ApplicationContext在读取配置文件后.实例化bean前后.设置bean的属性前后这些点都可以通过实现接口添加我 ...
随机推荐
- 为何滴滴会走Uber之路,研发无人驾驶?
近日,滴滴出行宣布完成新一轮超过55亿美元融资,以支持其全球化战略的推进和前沿技术领域的投资.其中,无人驾驶汽车将是这笔资金重要的投资方向.此前,滴滴在全球范围内的追赶对象Uber不断在无人汽车领域发 ...
- kafka相关问题总结
一直在使用kafka,遇到过很多问题,总结一下 很多人对比kafka和AMQP的时候,都会强调kafka会丢数据,感觉好像只要用kafka就会丢数据一样,从而排斥使用kafka,亦或者在使用的过程中, ...
- python基础-流程控制语句
所谓流程控制,就是在程序里面设定一些条件判断语句,满足哪条,就执行哪条 #if 单分支 if 条件: 满足条件后执行的代码 #例子 > : print()#结果为666 双分支 if 条件: 满 ...
- Think 框架漏洞利用
下午有点闲,又没有女朋友陪,该干嘛呢??? 对了,做安全的是不需要女朋友的,哈哈哈哈哈 废话不多说,本机搭建环境: 首先nmap扫描一下,哦哈,有点东西. 开的端口有点多,这个时候有点窃喜,开的端口太 ...
- 使用移动自适应布局+easy mock实现移动界面的简单实现
一.使用easy mock模拟数据 easy mock链接地址 二.自己写移动自适应布局 自己编写主要是利用rem进行宽度栅格布局: html { /* 相当于一个界面适配器,pc以及移动端都可以进行 ...
- 利用ajax 引入静态页公共的头部与底部
利用ajax引入公共的头部与底部或者多个页面需要用到的重复的组件,对于新入门的前端来说是很实用的方法,自己也是新手菜鸟一枚,折腾了好久,实现的方法有很多种,这是我个人觉得比较简单方便的 首先得把公用的 ...
- post请求与get请求的差别
幂等的概念 在理解这两者的区别前需要先了解的概念: 幂等性在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.简单的说就是,浏览器发起一次请求和多次请求,不会改变目标资源的状 ...
- Ubuntu16.04如何安装bazel?
官方文档:https://docs.bazel.build/versions/master/install-ubuntu.html 我没有使用二进制的安装方法,以下是二进制的安装方法: Install ...
- redis如何在spring里面的bean配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- Ubuntu部署Asp.net core网站无法访问
前几天应工作需要,在阿里云上部署一个测试站点.本以为分分钟的事情,没想到打脸了. 当时直接新建一个webapi项目,publish后直接上传到阿里云,随后设置nginx转发网站端口5000. 接着打开 ...