温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Netty分布式抽象编码器MessageToByteEncoder逻辑的示例分析

发布时间:2022-03-29 13:47:04 来源:亿速云 阅读:110 作者:小新 栏目:开发技术

小编给大家分享一下Netty分布式抽象编码器MessageToByteEncoder逻辑的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

MessageToByteEncoder

同解码器一样, 编码器中也有一个抽象类叫MessageToByteEncoder, 其中定义了编码器的骨架方法, 具体编码逻辑交给子类实现

解码器同样也是个handler, 将写出的数据进行截取处理, 我们在学习pipeline中我们知道, 写数据的时候会传递write事件, 传递过程中会调用handler的write方法, 所以编码器码器可以重写write方法, 将数据编码成二进制字节流然后再继续传递write事件

首先看MessageToByteEncoder的类声明

public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdapter{
    //省略类体
}

这里继承ChannelOutboundHandlerAdapter, 说明是个outBoundhandler, 我们知道write事件是个outBound事件, 而outBound事件只能通过outBoundHandler进行传输

write事件传播过程中要调用handler的write方法

我们跟到MessageToByteEncoder的write方法中:

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    ByteBuf buf = null;
    try {
        if (acceptOutboundMessage(msg)) {
            @SuppressWarnings("unchecked")
            I cast = (I) msg;
            buf = allocateBuffer(ctx, cast, preferDirect);
            try {
                encode(ctx, cast, buf);
            } finally {
                ReferenceCountUtil.release(cast);
            }

            if (buf.isReadable()) {
                ctx.write(buf, promise);
            } else {
                buf.release();
                ctx.write(Unpooled.EMPTY_BUFFER, promise);
            }
            buf = null;
        } else {
            ctx.write(msg, promise);
        }
    } catch (EncoderException e) {
        throw e;
    } catch (Throwable e) {
        throw new EncoderException(e);
    } finally {
        if (buf != null) {
            buf.release();
        }
    }
}

首先通过 if (acceptOutboundMessage(msg)) 判断当前对象是否可处理

如果可处理, 则进入if块中的逻辑, 如果不能处理, 则进入else块, 通过ctx.write(msg, promise)继续传递write事件

我们看if块中

 I cast = (I) msg 这里是强制类型转换, 转换成I类型, I类型是个泛型, 具体类型由用户定义

 buf = allocateBuffer(ctx, cast, preferDirect) 这里进行缓冲区分配

跟到allocateBuffer方法中

protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg, 
                           boolean preferDirect) throws Exception {
    if (preferDirect) {
        return ctx.alloc().ioBuffer();
    } else {
        return ctx.alloc().heapBuffer();
    }
}

这里会直接通过ctx的内存分配器进行内存分配, 通过判断preferDirect来分配堆内存或者堆外内存, 默认情况下是分配堆外内存

有关内存分配, 我们之前已经做过相关的剖析

回到write方法中:

内存分配结束之后会调用encode(ctx, cast, buf)方法进行编码, 该类由子类实现

子类可以通过继承该类, 重写encode方法, 将参数对象cast编码成字节写入到传入的ByteBuf中, 就完成了编码工作

编码完成后后, 会通过ReferenceCountUtil.release(cast)将cast对象释放

 if (buf.isReadable()) 这里判断buf是否有可读字节, 如果有可读字节, 则继续传递write事件

如果没有可读字节, 则将buf进行释放, 继续传播write事件, 传递一个空的ByteBuf

最后将buf设置为空

以上是“Netty分布式抽象编码器MessageToByteEncoder逻辑的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI