Netty的SimpleChannelInboundHandler分析

  • io.netty.channel.SimpleChannelInboundHandler是一个ChannelInboundHandler,它允许只处理一种明确的消息,这个消息的类型由泛型参数指定,例如String。
  • 这个类还有一个默认的特性,就是读过消息以后,可以将消息自动释放。如果读过消息以后不希望将消息继续传递给ChannelPipeline中后续的ChannelHandler,这个特性是有帮助的。
  • 当然,如果读过消息以后不希望自动释放,那么可以在创建SimpleChannelInboundHandler子类的实例的时候,调用SimpleChannelInboundHandler的构造函数SimpleChannelInboundHandler(boolean
    autoRelease),将构造函数中的参数autoRelease的值设置为false。如果不设置,默认为true。
  • SimpleChannelInboundHandler这个是一个抽象类,一个必须子类实现的函数是channelRead0(ChannelHandlerContext ctx, I msg)。但这个函数不是ChannelInboundHandler中的方法,而是SimpleChannelInboundHandler自己增加的方法。
  • channelRead0(ChannelHandlerContext ctx, I msg)这个方法会被channelRead(ChannelHandlerContext ctx, Object msg)方法调用。
  • 当Channel从对端读取到消息后,会调用channelRead(ChannelHandlerContext ctx, Object msg)方法,而channelRead(ChannelHandlerContext ctx, Object msg)方法会调用channelRead0(ChannelHandlerContext ctx, I msg)方法,所以SimpleChannelInboundHandler的子类实现channelRead0(ChannelHandlerContext ctx, I msg)方法即可。

我们看看SimpleChannelInboundHandler中channelRead(ChannelHandlerContext ctx, Object msg)方法的实现:

复制代码
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    boolean release = true;
    try {
        if (acceptInboundMessage(msg)) {
            @SuppressWarnings("unchecked")
            I imsg = (I) msg;
            channelRead0(ctx, imsg);
        } else {
            release = false;
            ctx.fireChannelRead(msg);
        }
    } finally {
        if (autoRelease && release) {
            ReferenceCountUtil.release(msg);
        }
    }
}
  • 上面源代码中,channelRead0(ctx, imsg)这条语句就是调用了被子类实现的channelRead0方法。

  • 下面再分析下if条件判断的逻辑:

    if (autoRelease && release) {

    ReferenceCountUtil.release(msg);

    }

这个if判断语句中,autoRelease就是构造函数传入的值,如果不传的话默认为true。当传入channelRead函数的消息类型跟泛型参数中的类型一致时,这个消息可以被处理,此时release的值为true。如果传入的消息跟泛型参数中指定的类型不同时,release的值被设置为false,这个消息不会被处理,只会简单地传递给ChannelPipeline中后续的ChannelHandler处理,这就是所谓的只明确处理一种消息的含义。

ReferenceCountUtil.release(msg)这个函数的作用就是将msg的引用计数减少1。如果引用计数减少到0,那么就将msg释放。当然,前提是msg实现了io.netty.util.ReferenceCounted接口。如果没有实现该接口,那么ReferenceCountUtil.release(msg)这条语句等于什么也没有做。

相关推荐
加号3几秒前
【C#】WPF基于Halcon 的HWindowControlWPF 控件实现图像缩放、移动
开发语言·c#·wpf
小英雄大肚腩丶2 分钟前
RabbitMQ消息队列
java·数据结构·spring boot·分布式·rabbitmq·java-rabbitmq
fengxin_rou14 分钟前
用户模块架构实战:DTO 与 Domain 分层、Optional 空值处理、事务只读优化详解
java·后端·架构·用户实战
ComputerInBook17 分钟前
C++ 中的 lambda 表达式
开发语言·c++·lambda表达式·匿名函数
ZC跨境爬虫32 分钟前
跟着 MDN 学 HTML day_52:(深入 XPathExpression 接口)
开发语言·前端·javascript·ui·html·音视频
yuanpan1 小时前
Python + Selenium 浏览器自动化测试与网页自动登录
开发语言·python·selenium
Wy_编程1 小时前
Go语言中的指针
开发语言·后端·golang
不想写代码的星星1 小时前
C++协程从入门到放弃?不,是从入门到手搓调度器
开发语言·c++
redaijufeng1 小时前
C++构造函数详解:从基础原理到实际应用
java·jvm·c++
lolo大魔王1 小时前
Go语言数据库操作之GORM框架从入门到生产实战(完整版)
开发语言·数据库·golang