资讯专栏INFORMATION COLUMN

MessagePack 编解码

xuxueli / 2770人阅读

摘要:是一个高效的二进制序列化框架它像一样支持不同语言间的数据交换但是它的性能更快序列化之后的码流更小的特点如下编解码高效性能高序列化之后的码流小支持跨语言编码器和解码器开发编码器开发负责将类型的对象编码为数组然后添加到集合中解码器开发首先从数

MessagePack 是一个高效的二进制序列化框架, 它像 JSON 一样支持不同语言间的数据交换, 但是它的性能更快, 序列化之后的码流更小.

MessagePack 的特点如下:

编解码高效, 性能高.

序列化之后的码流小.

支持跨语言.

MessagePack 编码器和解码器开发

    io.netty
    netty-all
    5.0.0.Alpha1
MessagePack 编码器开发
public class MsgpackEncoder extends MessageToMessageEncoder {
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        MessagePack msgpack = new MessagePack();
        byte[] bytes = msgpack.write(msg);
        out.add(bytes);
    }
}

负责将 Object 类型的 POJO 对象编码为 byte 数组, 然后添加到集合中.

MessagePack 解码器开发
public class MsgpackDecoder extends MessageToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception {
        int length = msg.readableBytes();
        byte[] array = new byte[length];

        msg.getBytes(msg.readerIndex(), array, 0 , length);

        MessagePack msgpack = new MessagePack();
        out.add(msgpack.read(array));
    }
}

首先从数据报 msg 中获取需要解码的 byte 数组, 然后调用 MessagePackread 方法将其反序列化为 Objcet 对象, 将解码后的对象加入到 List 集合中. 这样就完成了 MessagePack 的解码操作.

粘包/半包支持
ch.pipeline().addLast("frameDecoder",
                        new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2));

ch.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
ch.pipeline().addLast("msgpack encoder", new MsgpackEncoder());

利用 LengthFieldBasedFrameDecoderLengthFieldPrepender, 结合新开发的 MessagePack 编解码框架, 实现对 TCP 粘包/半包支持.

MessagePack 编码器之前增加 LengthFieldPrepender, 它将在 ByteBuf 之前增加 2 个字节的消息长度字段.

+----------------+    +--------+----------------+
| "HELLO, WORLD" |--->+ 0x000C | "HELLO, WORLD" |
+----------------+    +--------+----------------+

MessagePack 解码器之前增加 LengthFieldBasedFrameDecoder, 用于处理半包消息, 这样后面的 MsgpackDecoder 接收到的永远是整包消息.

+--------+----------------+    +----------------+
+ 0x000C | "HELLO, WORLD" |--->| "HELLO, WORLD" |
+--------+----------------+    +----------------+

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72785.html

相关文章

  • 造轮子系列(二): 史上最简单的长连接通信协议及实现

    摘要:背景现在写客户端或者网页的时候越来越多的需要与长连接打交道尤其是在这个老板动不动就要搞一个聊天系统的时代后端大哥们于是分分钟就能造一个基于或者的消息协议出来但是问题在于每做一个新项目后端大哥们就能造出一个新协议而且能有各种神奇的限制比如说要 背景 现在写客户端或者网页的时候, 越来越多的需要与长连接打交道, 尤其是在这个老板动不动就要搞一个聊天系统的时代, 后端大哥们于是分分钟就能造一...

    Alliot 评论0 收藏0
  • JavaScript中三种GBK/GB2312解码方案对比

    摘要:笔者在编码详解与中编码实践一文中介绍了中编码相关的基础知识,其中没有介绍纯粹的编解码方案,笔者后来根据网上的代码完善了下这个库,并且对中三种不同的编解码方案进行了比较。 Isomorphic Urlencode Here is English Version For README 笔者在URL编码详解与DOM中GBK编码实践一文中介绍了JavaScript中URL编码相关的基础知识,其...

    BlackFlagBin 评论0 收藏0
  • 基于 Netty 的可插拔业务通信协议的实现「3」业务注册及实际工作流程

    摘要:本文仍以该实例为例,探讨该自定义通信协议的具体工作流程,以及如何以注册的形式灵活插拔通信消息对象。进行二进制数据帧的解码操作时,数据帧中已包含了消息的功能位,据此可获取相应的编解码器,而后可以对该数据帧进行解析,生成相应的消息对象。 本文为该系列的第三篇文章,设计需求为:服务端程序和众多客户端程序通过 TCP 协议进行通信,通信双方需通信的消息种类众多。上一篇文章以一个具体的需求为例,...

    LdhAndroid 评论0 收藏0

发表评论

0条评论

xuxueli

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<