在使用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

下面具体说下每个回调的具体含义:

  1. handlerAdded: 新建立的连接会按照初始化策略,把handler添加到该channel的pipeline里面,也就是channel.pipeline.addLast(new LifeCycleInBoundHandler)执行完成后的回调;
  2. channelRegistered: 当该连接分配到具体的worker线程后,该回调会被调用。
  3. channelActive:channel的准备工作已经完成,所有的pipeline添加完成,并分配到具体的线上上,说明该channel准备就绪,可以使用了。
  4. channelRead:客户端向服务端发来数据,每次都会回调此方法,表示有数据可读;
  5. channelReadComplete:服务端每次读完一次完整的数据之后,回调该方法,表示数据读取完毕;
  6. channelInactive:当连接断开时,该回调会被调用,说明这时候底层的TCP连接已经被断开了。
  7. channelUnREgistered: 对应channelRegistered,当连接关闭后,释放绑定的workder线程;
  8. handlerRemoved: 对应handlerAdded,将handler从该channel的pipeline移除后的回调方法。

最新文章

  1. python编码最佳实践之总结
  2. C#多线程开发中如何更新UI界面控件内容
  3. Oracle 删除重复的记录,只保留一条
  4. 使用Jsoup函数包抓取网页内容
  5. Redis批量导入数据
  6. 第一个leapmotion的小游戏
  7. gtest以及测试小结
  8. java中如何调用oracle存储过程
  9. PhpStorm 4.0 & 5.0 部署本地Web应用
  10. poj1260
  11. MyEclipse10.6、Maven、svn集成
  12. (转)mahout中k-means例子的运行
  13. 【转】linux grep命令
  14. MySQL 基础知识梳理学习(一)----系统数据库
  15. LP-KPN
  16. [Web Service] Tutorial Basic Concepts
  17. 《Java开发学习大纲文档》V6.0(已经不公布了,请查看第七版)
  18. Oracle(二)在 Mysql 的基础上学习 Oracle
  19. 第十次Scrum meeting
  20. Tensflow预测股票实例

热门文章

  1. Proto3:Arena分配指南
  2. 新浪微博PC端登录分析
  3. LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚
  4. Redis list实现原理 - 双向循环链表
  5. JMeter-完成批量的接口测试
  6. unittest实战(二):用例编写
  7. .NET平台编程语言的衰败
  8. Spring-Boot-应用可视化监控
  9. html5插件完成滚屏幕效果
  10. JSON Serialization/Deserialization in C#