io.netty学习(四)ChannelHandler

这篇具有很好参考价值的文章主要介绍了io.netty学习(四)ChannelHandler。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

正文

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:

io.netty学习(四)ChannelHandler

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

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

ChannelOutboundHandler

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

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

io.netty学习(四)ChannelHandler

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

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

ChannelDuplexHandler

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

总结

以上就是关于ChannelHandler的分析,相信你对ChannelHandler也有一定的了解,下期我们再来分析ChannelPipeline的源码。文章来源地址https://www.toymoban.com/news/detail-501121.html

到了这里,关于io.netty学习(四)ChannelHandler的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 设置word目录从正文开始记录页码,并解决word目录正常,但正文页脚处只显示第一页的页码

    设置word目录从正文开始记录页码,并解决word目录正常,但正文页脚处只显示第一页的页码

    问题详情1:如何设置目录从正文开始记录页码 问题详情2:word目录处的页码正常,但正文只有第一页的页脚处显示页码 在设置目录从正文开始记录页码时需在目录后插入分节符(相同的节可以把当前页的页脚链接到上一页,但是不同的节就不行,因此可以利用分节来从 正文

    2024年03月10日
    浏览(11)
  • io.netty学习(二)Netty 架构设计

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

    目录 前言 Selector 模型 SelectableChannel Channel 注册到 Selector SelectionKey 遍历 SelectionKey 事件驱动 Channel 回调 Future 事件及处理器 责任链模式 责任链模式的优缺点 ChannelPipeline 将事件传递给下一个处理器 总结 上一篇文章,我们对  Netty 做了一个基本的概述,知道什么是 Netty 以及

    2024年02月10日
    浏览(14)
  • io.netty学习(三)Channel 概述

    目录 前言 正文 Channel概述 Channel 特点 Channel 接口方法 ChannelOutboundInvoker AttributeMap 总结 前两篇文章我们已经对 Netty 进行了简单的了解和架构设计原理的剖析。 本篇文章我们就来开始对 Netty 源码的分析,首先我们来讲解 Netty 中 Channel 相关的功能和接口。 io.netty学习使用汇总

    2024年02月09日
    浏览(17)
  • 文件IO,目录IO的学习

    文件IO,目录IO的学习

    用法:#include“head.h”    -     在当前目录下寻找头文件 主函数的传参中,argc是传参的个数  ,const char *argv[]是一个指针数组,存放的指针类型数据 argv【n】,n=1/2/3 分别代表三个指针参数 标准示例:     off_t lseek(int fd, off_t offset, int whence);        功能:            

    2024年02月20日
    浏览(9)
  • 《Git入门实践教程》前言+目录

    版本控制系统(VCS)在项目开发中异常重要,但和在校大学生的交流中知道,这个重要方向并未受到重视。具备这一技能,既是项目开发能力的体现,也可为各种面试加码。在学习体验后知道,Git多样化平台、多种操作方式、丰富的资源为业内人士提供了方便的同时,也造成

    2024年02月10日
    浏览(49)
  • 目录IO 2月19日学习笔记

    目录IO 2月19日学习笔记

     1. lseek        off_t lseek(int fd, off_t offset, int whence);        功能:             重新设定文件描述符的偏移量        参数:             fd:文件描述符             offset:偏移量             whence:                 SEEK_SET    文件开头                 SEEK_CUR    文件当前

    2024年02月20日
    浏览(10)
  • 嵌入式Linux学习DAY21--目录io

    嵌入式Linux学习DAY21--目录io

    对主函数传参: ./a.out +参数1(指针数组),参数2....... 在代码中,要写成 int main(参数数量,const char *指针数组) lseek(a,b,c):                功能:重新设定文件描述符的偏移量                参数:a:文件描述符                           b:偏移量         

    2024年02月20日
    浏览(12)
  • gateway报 netty堆外内存溢出问题解决io.netty.util.internal.OutOfDirectMemoryError

    gateway报 netty堆外内存溢出问题解决io.netty.util.internal.OutOfDirectMemoryError

    昨天线上网关突然无法访问。打开日志看到错误信息“io.netty.util.internal.OutOfDirectMemoryError” 堆外内存溢出。。这也没碰到过啊,看来今天准点下班的愿望又落空了。老规矩面向百度编程。先看看网上有没有其他兄弟碰到这个问题。一顿搜索之后发现,很多博客都是一知半解并

    2024年02月10日
    浏览(20)
  • Spingboot 整合netty-socket.io

    Spingboot 整合netty-socket.io

    依赖 注意版本号,不然client版本不对的话也是连不上的 https://github.com/mrniko/netty-socketio ​ `` 结构 3 配置 4 .ClientCache `` 5 . 连接处理类 6.工具处理类 7.NettySocketRunnable yaml 配置 8:nginx 配置 协议升级 wss(443) 或ws(80) 1: 注意server的版本和client版本是对应上的 2: 上线后注意线上是否

    2024年02月15日
    浏览(8)
  • 【redis问题】Caused by: io.netty.channel

    【redis问题】Caused by: io.netty.channel

    在使用 RedisTemplate 连接 Redis 进行操作的时候,发生了如下报错: 测试代码为: 配置文件:

    2024年02月11日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包