美文网首页
boy-learning-netty | 09 Netty 对常

boy-learning-netty | 09 Netty 对常

作者: BruceOuyang | 来源:发表于2019-10-17 17:16 被阅读0次

    相关源码:boy-learning-netty
    个人博客:http://bruce.bugmakers.club
    内容来自《极客时间 - Netty源码剖析与实战》

    Netty 对常用编解码的支持

    • 为什么需要 “二次” 解码

    • 常用的 “二次” 编解码方式

    • 选择编解码方式的要点

    • Protobuf 简介与使用

    • 源码解读:Netty 对常用编解码的支持

    为什么需要 “二次” 解码

    假设我们把解决粘包、半包问题的常见三种解码器叫一次解码器,那么,我们在项目中,除了可选的压缩解压缩之外,还需要一层解码,因为一次解码的结果是字节,需要和项目中所使用的的对象做转化,方便使用,这层解码器可以称为“二次解码器”,相应的,对应的编码器是为了将 Java 对象转化为字节流方便存储或传输。

    一次解码器的结果是字节,二次解码器的结果是对象

    • 一次解码器:ByteToMessageDecoder

      • io.netty.buffer.ByteBuf(原始数据流) -> io.netty.buffer.ByteBuf (用户数据流)
    • 二次解码器:MessageToMessageDecoder<I>

      • io.netty.buffer.ByteBuf (用户数据) -> Java Object

    思考:是不是可以一步到位?合并一次解码(解决粘包、半包)和二次解码(解决可操作性问题)

    可以,但是不建议

    • 没有分层,不够清晰

    • 耦合性高,不容易置换方案

    常用的 “二次” 编解码方式

    • Java 序列化:只有 java 能用,比较占空间

    • Marshaling:jboss

    • XML

    • JSON

    • MessagePack

    • Protobuf:性能好,可读性差

    • 其他

    选择编解码方式的要点

    • 空间:编码后占用空间大小,需要比较不同原始数据大小情况

    • 时间:编码后占用时间大小,需要比较不同原始数据大小情况

    • 是否追求可读性

    • 对多语言的支持

    Protobuf 简介与使用

    简介

    • Protobuf 是一个灵活的、高效的用于序列化数据的协议。

    • 相比较 XML 和 JSON 格式,Protobuf 更小、更快、更便捷。

    • Protobuf 是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以自动生成Java、python、C++等代码,不需要在写其他代码。

    使用

    • 下载对应操作系统的 protoc

    • 编写 .proto 文件

    • 生成代码

    protoc.exe --java_out=. demo.proto
    protoc.exe --python_out=. demo.proto
    protoc.exe --cpp_out=. demo.proto
    

    源码解读:Netty 对常用编解码的支持

    • netty 原代码的 netty-codec 模块下可以看到 netty 支持的编解码方式

    • netty 使用 Protobuf 编解码示例

    // 参考源代码:WorldClockClientInitializer.java
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        if (sslCtx != null) {
            p.addLast(sslCtx.newHandler(ch.alloc(), WorldClockClient.HOST, WorldClockClient.PORT));
        }
        // varint 为可变长度
        p.addLast(new ProtobufVarint32FrameDecoder());
        p.addLast(new ProtobufDecoder(WorldClockProtocol.LocalTimes.getDefaultInstance()));
    
        p.addLast(new ProtobufVarint32LengthFieldPrepender());
        p.addLast(new ProtobufEncoder());
    
        p.addLast(new WorldClockClientHandler());
    }
    

    相关文章

      网友评论

          本文标题:boy-learning-netty | 09 Netty 对常

          本文链接:https://www.haomeiwen.com/subject/bqjvmctx.html