Netty之ChannelHandler(三)
ChannelHandler是netty中的核心处理部分,我们使用netty的绝大部分代码都写在这部分,所以了解它的一些机制和特性是很有必要的。
一、Channel
Channel接口抽象了底层socket的一些状态属性以及调用方法
针对不同类型的socket提供不同的子类实现。
二、Channel生命周期
三、ChannelHandler
ChannelHandler用于处理Channel对应的事件
ChannelHandler接口里面只定义了三个生命周期方法,我们主要实现它的子接口ChannelInboundHandler和ChannelOutboundHandler,为了便利,框架提供了ChannelInboundHandlerAdapter,ChannelOutboundHandlerAdapter和ChannelDuplexHandler这三个适配类,在使用的时候只需要实现你关注的方法即可
ChannelHandler生命周期方法:
ChannelHandler里面定义三个生命周期方法,分别会在当前ChannelHander加入ChannelHandlerContext中,从ChannelHandlerContext中移除,以及ChannelHandler回调方法出现异常时被回调。
四、ChannelInboundHandler 和 ChannelOutboundHandler
1. ChannelInBoundHandler
介绍一下这些回调方法被触发的时机:
回调方法 | 触发时机 | client | server |
---|---|---|---|
channelRegistered | 当前channel注册到EventLoop | true | true |
channelUnregistered | 当前channel从EventLoop取消注册 | true | true |
channelActive | 当前channel激活的时候 | true | true |
channelInactive | 当前channel不活跃的时候,也就是当前channel到了它生命周期尾 | true | true |
channelRead | 当前channel从远端读取到数据 | true | true |
channelReadComplete | channel read消费完读取的数据的时候被触发 | true | true |
userEventTriggered | 用户事件触发的时候 | ||
channelWritabilityChanged | channel的写状态变化的时候触发 |
可以注意到每个方法都带了ChannelHandlerContext作为参数,具体作用是,在每个回调事件里面,处理完成之后,使用ChannelHandlerContext的fireChannelXXX方法来传递给下个ChannelHandler,netty的codec模块和业务处理代码分离就用到了这个链路处理。
2. ChannelOutboundHandler
回调方法 | 触发时机 | client | server |
---|---|---|---|
bind | bind操作执行前触发 | false | true |
connect | connect 操作执行前触发 | true | false |
disconnect | disconnect 操作执行前触发 | true | false |
close | close操作执行前触发 | false | true |
deregister | deregister操作执行前触发 | ||
read | read操作执行前触发 | true | true |
write | write操作执行前触发 | true | true |
flush | flush操作执行前触发 | true | true |
注意到一些回调方法有ChannelPromise这个参数,我们可以调用它的addListener注册监听,当回调方法所对应的操作完成后,会触发这个监听。
下面这个代码,会在写操作完成后触发,完成操作包括成功和失败:
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { ctx.write(msg,promise); System.out.println("out write"); promise.addListener(new GenericFutureListener<Future<? super Void>>() { @Override public void operationComplete(Future<? super Void> future) throws Exception { if(future.isSuccess()){ System.out.println("OK"); } } }); }
3. ChannelInBoundHandler 和 ChannelOutboundHandler的区别
个人感觉in和out的区别主要在于ChannelInboundHandler的channelRead和channelReadComplete回调和ChannelOutboundHandler的write和flush回调上,ChannelOutboundHandler的channelRead回调负责执行入栈数据的decode逻辑,ChannelOutboundHandler的write负责执行出站数据的encode工作。其他回调方法和具体触发逻辑有关,和in与out无关。
五、ChannelHandlerContext
每个ChannelHandler通过add方法加入到ChannelPipeline中去的时候,会创建一个对应的ChannelHandlerContext,并且绑定,ChannelPipeline实际维护的是ChannelHandlerContext 的关系。
在DefaultChannelPipeline源码中可以看到会保存第一个ChannelHandlerContext以及最后一个ChannelHandlerContext的引用。
六、总结
上述组件的关系:
- 每个Channel会绑定一个ChannelPipeline,ChannelPipeline中也会持有Channel的引用
- ChannelPipeline持有ChannelHandlerContext链路,保留ChannelHandlerContext的头尾节点指针
- 每个ChannelHandlerContext会对应一个ChannelHandler,也就相当于ChannelPipeline持有ChannelHandler链路
- ChannelHandlerContext同时也会持有ChannelPipeline引用,也就相当于持有Channel引用
- ChannelHandler链路会根据Handler的类型,分为InBound和OutBound两条链路
Netty之ChannelHandler(三)的更多相关文章
- Netty中的三种Reactor(反应堆)
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
- Netty 系列(三)Netty 入门
Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...
- Netty的ChannelHandler,ChannelHandlerContext,ChannelPipeline
本小节一起学习一下ChannelHandler,ChannelHandlerContext,ChannelPipeline这三个Netty常用的组件,不探究它们的底层源码,我们就简单的分析一下用法 首 ...
- Netty入门(三)之web服务器
Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...
- Netty Reator(三)Reactor 模型
Netty Reator(三)Reactor 模型 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) 本文介绍 DC Sch ...
- Netty 学习(三):通信协议和编解码
Netty 学习(三):通信协议和编解码 作者: Grey 原文地址: 博客园:Netty 学习(三):通信协议和编解码 CSDN:Netty 学习(三):通信协议和编解码 无论使用 Netty 还是 ...
- 【Netty】ChannelHandler和ChannelPipeline
一.前言 前面学习了Netty的ByteBuf,接着学习ChannelHandler和ChannelPipeline. 二.ChannelHandler和ChannelPipeline 2.1 Cha ...
- 【Netty】ChannelHandler和codec
一.前言 前面学习了Netty的codec框架,下面接着学习ChannelHandler与codec之间的关联. 二.ChannelHandler和codec Netty为不同的协议提供了处理器和编解 ...
- Netty学习笔记(三)——netty源码剖析
1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...
随机推荐
- 【转】ServletContext介绍及用法
1.1. 介绍 ServletContext官方叫servlet上下文.服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象.这个对象全局唯一,而且工程内部的所有servl ...
- Dockerfile命令整理
通过Dockerfile只做Docker镜像时,需要用到Dockerfile的命令,收集整理如下,以便后续翻阅参考. FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么 ...
- vue使用--saas的引入与使用
什么是saas.scss? saas是一种动态样式语言,属于CSS预处理器,为CSS增加了一些编程特性,比如变量.嵌套.函数.继承.运算等等.开发人员可以像使用js等语言一样使用saas进行css的 ...
- django 使用HttpResponse返回json数据为中文
之前我用django一般用JsonResponse来返回json数据格式 但是发现返回中文的时候会乱码 from django.http import JsonResponse def test(re ...
- Windows安装RabbitMQ并设置数据存储目录
一.安装Elang 下载otp_win64_xx.x.exe,当前使用otp_win64_21.3.exe版本,按步骤完成安装. 下载地址:http://www.erlang.org/download ...
- JVM调优YoungGC
先上代码: 主函数: public class GCDemo { public static void main(String[] args) throws InterruptedEx ...
- java基本类型包装类之间的值比较问题
废话不多说,先看代码 Integer a = 2;Integer b = 2;if(a==b){ System.out.println("相等");}else{ System.ou ...
- 项目整合SpringDataRedis
1:准备工作 先导入redis和jedis依赖,在配置redis-config.properties 和applicationContext-redis.xml (详细配置信息及入门demo见我上一篇 ...
- Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖
Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coord ...
- vue入门案例
1.技术在迭代,有时候你为了生活没有办法,必须掌握一些新的技术,可能你不会或者没有时间造轮子,那么就先把利用轮子吧. <!DOCTYPE html> <html> <he ...