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 ...
随机推荐
- luoguP3975 [TJOI2015]弦论
题意 第一问有一个经典做法:学习笔记 对于第二问,其实就是对于一个状态的所有串,第一问看成一个,第二问看成多个. code: #include<bits/stdc++.h> using n ...
- luoguP2824 [HEOI2016/TJOI2016]排序(二分答案做法)
题意 这题的思路实在巧妙. 首先我们肯定无法对区间进行sort,那么考虑如何使得sort简化. 问:如果给的序列是一个0-1序列,让你区间排序,那么怎么做? 答:建一颗线段树维护sum,求出当前区间中 ...
- Linux学习笔记-第16天 这些个配置参数好饶阿
原理是懂了,但是配置参数好多阿,难道这些都要记么...呃
- 【shell脚本】定时备份数据库===dbbackup.sh
定时备份数据库是很有必要的 一.脚本内容 [root@localhost dbbackup]# cat dbbackup.sh #!/bin/bash #备份数据库 mysqldump -uroot ...
- jQuery 源码解析(八) 异步队列模块 Callbacks 回调函数详解
异步队列用于实现异步任务和回调函数的解耦,为ajax模块.队列模块.ready事件提供基础功能,包含三个部分:Query.Callbacks(flags).jQuery.Deferred(funct) ...
- Vue.js 源码分析(三十) 高级应用 函数式组件 详解
函数式组件比较特殊,也非常的灵活,它可以根据传入该组件的内容动态的渲染成任意想要的节点,在一些比较复杂的高级组件里用到,比如Vue-router里的<router-view>组件就是一个函 ...
- SQL Server 通过“with as”方法查询树型结构
一.with as 公用表表达式 类似VIEW,但是不并没有创建对象,WITH AS 公用表表达式不创建对象,只能被后随的SELECT语句,其作用: 1. 实现递归查询(树形结构) 2. 可以在一个 ...
- WPF DataGrid使用DataTable为数据源,添加CheckBox列使用Delete删除行的方法
首先将CanUserDeleteRows设置为False, 其次是设置KeyUp事件 并自定义DataGrid.Columns修改如下 <DataGrid x:Name="DG&quo ...
- 【杂文】CSP2019蒟蒻AFO(假)记
[杂文]CSP2019蒟蒻AFO(假)记 [初赛前 N 天] 时间:2019-10-15 今晚 \(2012\) 的初赛题做到心态爆炸,选择考计算机基础知识一脸懵逼,填空和后面一道大模拟直接跳过,最后 ...
- opencv 图像旋转
理论 http://www.cnblogs.com/wangguchangqing/p/4045150.html 翻开任意一本图像处理的书,都会讲到图像的几何变换,这里面包括:仿射变换(affine ...