io.netty学习(四)ChannelHandler

news2024/7/6 19:40:28

目录

前言

正文

ChannelHandler

ChannelInboundHandler

ChannelOutboundHandler

ChannelDuplexHandler

总结


前言

先简略了解一下ChannelPipelineChannelHandler的概念。

想象一个流水线车间。当组件从流水线头部进入,穿越流水线,流水线上的工人按顺序对组件进行加工,到达流水线尾部时商品组装完成。可以将ChannelPipeline当做流水线,ChannelHandler当做流水线工人。源头的组件当做event,如read,write等等。

本篇文章我们先来讲讲ChannelHandler的相关知识,下面进入正文吧。

io.netty学习使用汇总 

正文

ChannelHandler

  • ChannelHandler并不处理事件,而由其子类代为处理:ChannelInboundHandler拦截和处理入站事件,ChannelOutboundHandler拦截和处理出站事件。

  • ChannelHandlerChannelHandlerContext通过组合或继承的方式关联到一起成对使用。事件通过ChannelHandlerContext主动调用如fireXXX()write(msg)等方法,将事件传播到下一个处理器。

注意:入站事件在ChannelPipeline双向链表中由头到尾正向传播,出站事件则方向相反。

ChannaleHandler 作为最顶层的接口,并不处理入站和出站事件,所以接口中只包含最基本的方法:

 // Handler本身被添加到ChannelPipeline时调用
 void handlerAdded(ChannelHandlerContext var1) throws Exception;
  // Handler本身被从ChannelPipeline中删除时调用
 void handlerRemoved(ChannelHandlerContext var1) throws Exception;
 
 // 发生异常时调用
 @Deprecated
 void exceptionCaught(ChannelHandlerContext var1, Throwable var2) throws Exception;

Sharable注解:

当客户端连接到服务器时,Netty新建一个ChannelPipeline处理其中的事件,而一个ChannelPipeline中含有若干ChannelHandler。如果每个客户端连接都新建一个ChannelHandler实例,当有大量客户端时,服务器将保存大量的ChannelHandler实例。为此,Netty提供了Sharable注解,如果一个ChannelHandler状态无关,那么可将其标注为Sharable,如此,服务器只需保存一个实例就能处理所有客户端的事件。

 @Inherited
 @Documented
 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Sharable {
 }

作为ChannelHandler的默认实现,ChannelHandlerAdapter有个重要的方法isSharable(),代码如下:

 public boolean isSharable() {
     Class<?> clazz = this.getClass();
     // 每个线程一个缓存
     Map<Class<?>, Boolean> cache = InternalThreadLocalMap.get().handlerSharableCache();
     Boolean sharable = (Boolean)cache.get(clazz);
     if (sharable == null) {
         // Handler是否存在Sharable注解
         sharable = clazz.isAnnotationPresent(Sharable.class);
         cache.put(clazz, sharable);
     }
 
     return sharable;
 }

这里引入了优化的线程局部变量InternalThreadLocalMap,即每个线程都有一份ChannelHandler是否Sharable的缓存。这样可以减少线程间的竞争,提升性能。

ChannelInboundHandler

ChannelInboundHandler处理入站数据以及各种状态变化,当Channel状态发生改变会调用ChannelInboundHandler中的一些生命周期方法。这些方法与Channel的生命密切相关。

入站数据,就是进入socket的数据。下面展示一些该接口的生命周期API:

ChannelInboundHandlerAdapter作为ChannelInboundHandler的实现,默认将入站事件自动传播到下一个入站处理器。其中的代码高度一致,如下:

 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
     ctx.fireChannelRead(msg);
 }

ChannelOutboundHandler

出站操作和数据将由 ChannelOutboundHandler 处理。它的方法将被 Channel、 ChannelPipeline 以及 ChannelHandlerContext 调用。ChannelOutboundHandler 的一个强大的功能是可以按需推迟操作或者事件,这使得可以通过一些复杂的方法来处理请求。

例如, 如果到远程节点的写入被暂停了, 那么你可以推迟冲刷操作并在稍后继续。

同理,ChannelOutboundHandlerAdapter作为ChannelOutboundHandler的事件,默认将出站事件传播到下一个出站处理器:

 @Override
 public void read(ChannelHandlerContext ctx) throws Exception {
     ctx.read();
 }

ChannelDuplexHandler

ChannelDuplexHandler则同时实现了ChannelInboundHandlerChannelOutboundHandler接口。如果一个所需的ChannelHandler既要处理入站事件又要处理出站事件,推荐继承此类。

总结

以上就是关于ChannelHandler的分析,相信你对ChannelHandler也有一定的了解,下期我们再来分析ChannelPipeline的源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/664692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第四章 组合逻辑电路--数电(期末复习笔记)

第四章 组合逻辑电路 本章重点&#xff1a; 1. 组合逻辑电路的分析与设计方法 2. 常用组合逻辑模块的使用 4.1 概述 4.11 组合逻辑电路 任一时刻的输出仅取决于该时刻的输入&#xff0c;与电路原来的状态无关。4.12 时序逻辑电路 任一时刻的输出不仅取决于现时的输入&am…

电容的基本工作原理

目录 电容器的发展历程现象发现第一个存储电荷的元器件&#xff1a;莱顿瓶真正出名的时刻 为什么电容器的容量单位称为法拉&#xff1f;电容器和电容的区别电容的组成电介质与电解质对电容的影响电容是如何工作的通交流阻直流阻直流通交流 电容器的单位电容的容抗电容常见的种类…

Idea Mybatis插件:提高CRUD效率

mybatis-sql-viewer插件主要提供能力&#xff1a;将mybatis xml转成真实SQL语句、参数mock、SQL规范检查、SQL索引检查、SQL运行、SQL压测及Mybatis SQL语句扫描。 1. 简介 虽然写了很久的CRUD&#xff0c;但是依旧觉得写好CRUD是一件非常难且麻烦的事情&#xff0c;以下的情…

chatgpt赋能Python-python找出不同部分

介绍 在SEO&#xff08;Search Engine Optimization&#xff09;领域&#xff0c;比较常见的问题之一是如何快速有效地查找出两段文本的不同部分。这对于优化网站内容或对比竞争对手的网站内容都非常有用。Python作为一种强大的编程语言&#xff0c;其特性和库使得这种任务变得…

神经网络入门①多层感知器如何解决异或问题?

文章目录 1. 多层感知器2. BP算法参考文献 1. 多层感知器 感知机&#xff08;perceptron&#xff09;早在20世纪50年代就提出来了1&#xff0c;但直到近几年深度学习的崛起&#xff0c;神经网络才再次走入大众的视野&#xff0c;并且成为了当下最热门的研究方向之一。 一个单层…

MybatisPlus的save方法

当我前端传递的是一个整合的数据模型Dto,需要同时插入俩张表,并且其中一张表的属性需要得到另一张表的id,如何实现呢?这个时候MP封装好的插入方法:save就起了很好的作用 public R<String> SaveNewDish(DishDto dishdto) { // 1. 保存菜品基本信息log.info("前…

MySQL优化--覆盖索引,超大分页查询

目录 覆盖索引 MYSQL超大分页处理 面试回答 大纲 回答 覆盖索引 覆盖索引是指查询使用了索引&#xff0c;并且需要返回的列&#xff0c;在该索引中已经全部能够找到 。 MYSQL超大分页处理 在数据量比较大时&#xff0c;如果进行limit分页查询&#xff0c;在查询时&#…

一步一步教你如何使用MMSelfSup框架【1】

介绍 任务介绍 自监督学习(Self-supervised learning, SSL)是一种极具潜力的学习范式&#xff0c;它旨在使用海量的无标注数据来进行表征学习。在SSL中&#xff0c;我们通过构造合理的预训练任务&#xff08;可自动生成标注&#xff0c;即自监督&#xff09;来进行模型的训练…

C#探索之路(8):初探.Net中官方文档OpCode的格式

C#探索之路(8)&#xff1a;初探.Net中官方文档OpCode的格式 文章目录 C#探索之路(8)&#xff1a;初探.Net中官方文档OpCode的格式1 前提2 疑惑1&#xff1a;Opcode格式是什么&#xff1f;3 答疑1&#xff1a;4 验证方式&#xff1a;5 总结 1 前提 最近在尝试了解学习这个OpCod…

使用ChatGPT最新版实现批量写作,打造丰富多彩的聚合文章

随着人工智能的迅猛发展&#xff0c;ChatGPT最新版作为一种自然语言处理模型&#xff0c;可以为我们提供强大的文本生成能力。在这篇文章中&#xff0c;我们将探讨如何利用ChatGPT最新版来实现批量写作&#xff0c;从而打造丰富多彩的聚合文章。 一、ChatGPT最新版简介 Chat…

使用mpi并行技术实现快排Qsort()

快排基本原理&#xff1a; 快速排序可以说是最为常见的排序算法&#xff0c;冒泡排序时间复杂度达到了O&#xff08;N2&#xff09;&#xff0c;而桶排序容易造成浪费空间。快排&#xff08;Quicksort&#xff09;就成为了不错的选择。 1、原理&#xff1a;快排需要找一个数作…

基于 JavaScript 中的 Date 类型实现指定日期和天数的加减运算

文章目录 Intro基本方法构造方法--如何初始化一个Date对象&#xff1f;Date 对象的天数加减法 【工具方法封装】最后 Intro 刚才突然想到&#xff0c;我还有多久就要过27岁的生日了呢。 年近三十&#xff0c;一事无成。 以下基于 JavaScript 中的 Date 对象封装一些方法。 基…

CAS、AtomicInteger和LongAdder原理

目录 一、CAS 1、介绍 2、CAS与volatile 3、为什么无锁效率高 4、总结 二、原子整数 三、原子引用 1、介绍 2、ABA问题 3、AtomicStampedReference 4、AtomicStampedReference 四、原子累加器 1、介绍 2、LongAdder重要关键域 CAS锁 原理之伪共享 3、LongAdde…

Java性能权威指南-总结15

Java性能权威指南-总结15 堆内存最佳实践对象生命周期管理弱引用、软引用与其他引用 小结 堆内存最佳实践 对象生命周期管理 弱引用、软引用与其他引用 在Java中&#xff0c;弱引用和软引用也支持对象重用&#xff0c;不过作为开发者&#xff0c;并不会经常从重用的角度看待…

【C语言进阶】文件操作

目录 &#x1f945;什么是文件&#xff1a; &#x1f3d1;程序文件&#xff1a;&#x1f3d1;数据文件&#xff1a; &#x1f3d1;文件名&#xff1a; &#x1f945;文件的打开和关闭&#xff1a;&#x1f3d1;文件指针&#xff1a; &#x1f3d1;fopen和fclose&#xff1a; &a…

基于matlab使用先导校准来补偿阵列不确定性(附源码)

一、前言 此示例说明如何使用先导校准来提高天线阵列在存在未知扰动时的性能。 原则上&#xff0c;可以轻松设计理想的均匀线性阵列&#xff08;ULA&#xff09;来执行阵列处理任务&#xff0c;例如波束成形或到达方向估计。在实践中&#xff0c;没有理想的阵列。例如&#xff…

io.netty学习(二)Netty 架构设计

目录 前言 Selector 模型 SelectableChannel Channel 注册到 Selector SelectionKey 遍历 SelectionKey 事件驱动 Channel 回调 Future 事件及处理器 责任链模式 责任链模式的优缺点 ChannelPipeline 将事件传递给下一个处理器 总结 前言 上一篇文章&#xff…

1.react路由的基本使用

第一步 首先打开index.js&#xff0c;在里面引入BrowserRouter或者HashRouter&#xff0c;启用全局路由模式。 BrowserRouter与HashRouter的区别 // index.js import React from react; import ReactDOM from react-dom/client; import ./index.css; import App from ./App;…

P31[10-1]软件模拟IIC通信协议(使用stm32库函数)(内含:实物连接+IIC时序解释+硬件电路+IIC基本时序单元(起始 终止 发送接收 ))

IIC通讯分为硬件读写IIC和软件IIC,以下为软件读写IIC 实物连接如下: 解释: 软件IIC通讯,对MPU6050芯片内部的寄存器进行读写操作,。写入配置寄存器,即可对外挂模块进行配置。。读出数据寄存器,即可获取外挂模块的数据。。。 OLED第一行为设备ID号(固定,有些可能不同)…

基于Springboot+mybatis+mysql+html图书管理系统2

基于Springbootmybatismysqlhtml图书管理系统2 一、系统介绍二、功能展示1.用户登陆2.用户主页3.图书查询4.还书5.个人信息修改6.图书管理&#xff08;管理员&#xff09;7.学生管理&#xff08;管理员&#xff09;8.废除记录&#xff08;管理员&#xff09; 三、数据库四、其它…