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的引用。

六、总结

上述组件的关系:

  1. 每个Channel会绑定一个ChannelPipeline,ChannelPipeline中也会持有Channel的引用
  2. ChannelPipeline持有ChannelHandlerContext链路,保留ChannelHandlerContext的头尾节点指针
  3. 每个ChannelHandlerContext会对应一个ChannelHandler,也就相当于ChannelPipeline持有ChannelHandler链路
  4. ChannelHandlerContext同时也会持有ChannelPipeline引用,也就相当于持有Channel引用
  5. ChannelHandler链路会根据Handler的类型,分为InBound和OutBound两条链路

Netty之ChannelHandler(三)的更多相关文章

  1. Netty中的三种Reactor(反应堆)

    目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...

  2. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  3. Netty的ChannelHandler,ChannelHandlerContext,ChannelPipeline

    本小节一起学习一下ChannelHandler,ChannelHandlerContext,ChannelPipeline这三个Netty常用的组件,不探究它们的底层源码,我们就简单的分析一下用法 首 ...

  4. Netty入门(三)之web服务器

    Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...

  5. Netty Reator(三)Reactor 模型

    Netty Reator(三)Reactor 模型 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) 本文介绍 DC Sch ...

  6. Netty 学习(三):通信协议和编解码

    Netty 学习(三):通信协议和编解码 作者: Grey 原文地址: 博客园:Netty 学习(三):通信协议和编解码 CSDN:Netty 学习(三):通信协议和编解码 无论使用 Netty 还是 ...

  7. 【Netty】ChannelHandler和ChannelPipeline

    一.前言 前面学习了Netty的ByteBuf,接着学习ChannelHandler和ChannelPipeline. 二.ChannelHandler和ChannelPipeline 2.1 Cha ...

  8. 【Netty】ChannelHandler和codec

    一.前言 前面学习了Netty的codec框架,下面接着学习ChannelHandler与codec之间的关联. 二.ChannelHandler和codec Netty为不同的协议提供了处理器和编解 ...

  9. Netty学习笔记(三)——netty源码剖析

    1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...

随机推荐

  1. layer icon样式及 一些弹框使用方法

    一.layer的icon样式 以上样式测试代码: layer.confirm('icon测试', {icon: 1, title:'提示'}, function(index){ //do someth ...

  2. WordPress更改“固定链接”后 ,页面出现404的解决方法

    一.Web服务器对应的是Nginx 解决方案:修改linux服务器下Nginx的配置文件,目录为:/usr/local/nginx/conf/nginx.conf, 也可以直接使用命令nginx -t ...

  3. Paper | Compression artifacts reduction by a deep convolutional network

    目录 1. 故事 2. 方法 3. 实验 这是继SRCNN(超分辨)之后,作者将CNN的战火又烧到了去压缩失真上.我们看看这篇文章有什么至今仍有启发的故事. 贡献: ARCNN. 讨论了low-lev ...

  4. github上计算String相似度好的项目

    项目中包含了杰卡德NGram.cosin夹角.最长公共子序列.边际距离等常用的相似度算法. https://github.com/tdebatty/java-string-similarity

  5. CSP-J&S2019前颓废记

    说了是颓废记,就是颓废记,因为真的很颓废...... 2018年12月 我看懂了<啊哈算法>(仅仅是看懂,并没有完全学会,只看得懂,却不会敲) 插曲:八上期末考试 我们老师阻挠我继续学OI ...

  6. nmap中文手册

    译注该Nmap参考指南中文版由Fei Yang <fyang1024@gmail.com>和Lei Li<lilei_721@6611.org> 从英文版本翻译而来. 我们希望 ...

  7. eclipse复制bpmn文件到idea下乱码问题处理

    1.最近在学习工作流,在eclipse上画完了流程图,然后复制到idea下,发现节点的汉字是乱码的. 2.处理方案是修改idea的配置文件,如图,打开这两个文件,在文件末尾加上 -Dfile.enco ...

  8. ubuntu 16.04 上编译和安装C++机器学习工具包mlpack并编写mlpack-config.cmake | tutorial to compile and install mplack on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/1cd6a04d/,欢迎阅读最新内容! tutorial to compile and install mplack on ubun ...

  9. matplotlib画预测框以及打标签

    https://blog.csdn.net/weixin_43338538/article/details/89003280 https://blog.csdn.net/yjl9122/article ...

  10. 如何在 C# 中自定义 Comparer,以实现按中文拼音(a-z)来排序

    1. 为何要自定义 Comparer a. 先看如下代码 class Program { public static void Main(string[] args) { List<string ...