谷歌开源项目ProtoBuf再探(与Netty相关)

简介: 谷歌开源项目ProtoBuf再探(与Netty相关)

题为谷歌开源项目ProtoBuf一探(基础环境配置)文章奠定了走进ProtoBuf的世界的路基,环境配置完成后,就正式地开启旅程。


第一站:ProtoBuf语义


既然是一门新的编程语言(使命是定义数据结构),我们就需要去掌握其中语义。学习其它任何语言都一样。语法规则搞懂了,剩下的就是逻辑码代码。以下面代码为例,附带注释。


syntax = "proto2";//定义协议版本,现在出来了proto3
package tutorial;//定义该文件的包名
option java_package = "com.example.tutorial";//定义输出java文件的包名
option java_outer_classname = "AddressBookProtos";//定义输出java文件的类名
message Person { //定义消息数据结构名称
  required string name = 1;//字段修饰
  required int32 id = 2;
  optional string email = 3;
  enum PhoneType {//定义枚举类型
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }
  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];//默认值为HOME=1
  }
  repeated PhoneNumber phones = 4;
}
message AddressBook {
  repeated Person people = 1;
}

从上述代码中可以看出,Person消息数据结构包含若干基本类型,如boolint32string,enum等。数据类型前有且仅有这三种修饰符。如下表所示。


修饰符 含义
required 字段属性为必须,否则消息被视为未初始化
optional 字段属性为可选,若该字段未被初始,就会持有其设置的默认值;也可以不设置,系统会设置默认值
repeated 字段属性为重复,重复的字段在Protocol Buffer中保存

在代码中,也能看到可以嵌套消息数据结构。这在输出的Java文件得出对应的嵌套静态常量类。这样就极大地丰富了自定义协议的灵活性。可以任意组合出N种类型的消息数据结构。

Protocol Buffer系统默认值如下表所示:

数据类型 默认值
int32 0
string 空字符串
enum 第一个值
bool false


如果枚举类型中,枚举类型的必须是32bit 的整数值;想让其中两个值相等,必须开启别号功能即option allow_alias = true,如下代码所述。


enum EnumAllowingAlias {
  option allow_alias = true;
  UNKNOWN = 0;
  STARTED = 1;
  RUNNING = 1;
}
enum EnumNotAllowingAlias {
  UNKNOWN = 0;
  STARTED = 1;
  // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.
}

其它需要注意的地方请参照官方指导1


第二站:入驻Netty城


Netty作为一种高扩展-异步-事件驱动型通信框架已经享誉国内外。在该框架中,拥有市场上存在的很多协议的编解码器,如HTTP,WebSocket,MQTT,SMTP,SSL等。这极大地缩短了开发者的研发周期。避免重复造轮子。

在写好ChannelInboundHandler或者ChannelOutboundHandler处理器后,就需要进行测试,或许你会采用开启客户端和服务端来看是否工作正常,这样显得太笨重了。而且有小问题也不容易查看出。这时一个嵌入的通道在Netty中应运而生,它就是EnbededChannel,它的两对方法极为重要。其余方法请看官方API2。如下表所示。


方法 作用
public boolean writeOutbound(Object… msgs) 向通道中写出站数据
public T readOutbound() 从通道中读经过出站处理器处理后的数据(如编码)
public boolean writeInbound(Object… msgs) 向通道中写出入站数据
public T readInbound() 从通道中读经过入站处理器处理后的数据(如解码)


当自定义好ProtoBuf协议后,编译出java文件,导入项目工程中。然后利用Netty自带的编解码器进行测试。代码如下。


@Test
    public void testAlarmProto(){
      //构建消息类型
        MessageProto.MessageBase.Header.Builder header =MessageProto.MessageBase.Header.newBuilder();
        header.setType(MessageProto.MessageBase.MessageType.SERVICE_REQ);
        MessageProto.MessageBase.Builder message = MessageProto.MessageBase.newBuilder();
        message.setHeader(header.build());
        //构建带有处理器的通道
        EmbeddedChannel ch = new EmbeddedChannel();
        ch.pipeline().addLast("frameDecoder",new ProtobufVarint32FrameDecoder());
        ch.pipeline().addLast("decoder",new ProtobufDecoder(MessageProto.MessageBase.getDefaultInstance()));
        ch.pipeline().addLast("frameEncoder",new ProtobufVarint32LengthFieldPrepender());
        ch.pipeline().addLast("encoder",new ProtobufEncoder());
        /**
         * TODO:先写入数据进行编码,然后再读出数据进行解码
         */
        ch.writeOutbound(message.build());
        ByteBuf byteBuf = ch.readOutbound();
        System.out.println(byteBuf.toString());
        ch.writeInbound(byteBuf);
        ch.finish();
        MessageProto.MessageBase messageBase = ch.readInbound();
        System.out.println(messageBase.getHeader().getType().getNumber());
        System.out.println(messageBase.getBody().getContext().getBuildingPart());
    }

能够从POJO到POJO就表示成功 ? 。


https://developers.google.com/protocol-buffers/docs/proto ↩︎


https://netty.io/4.1/api/index.html ↩︎


相关文章
|
8天前
|
网络协议 Java 测试技术
阿里内部Netty实战小册,值得拥有
Netty 是一个高性能的 Java 网络通信框架,简化了网络编程并涵盖了最新的Web技术。它提供了一种抽象,降低了底层复杂性,使得更多开发者能接触网络编程。Netty 因其易用性、高效性和广泛的应用场景受到推崇,适合互联网行业从业者学习,有助于理解和开发基于Netty的系统。免费的《Netty实战小册》详细介绍了Netty的各个方面,包括概念、架构、编解码器、网络协议和实际案例,帮助读者深入理解和应用Netty。如需完整版小册,可点击链接获取。
阿里内部Netty实战小册,值得拥有
|
8天前
|
Dubbo 网络协议 NoSQL
阿里巴巴的Netty面试题到底有多难,这些知识你能掌握多少?
Netty 是一个可以快速开发网络应用程序的 NIO 框架,它大大简化了 TCP 或者 UDP 服务器的网络编程。Netty 的简易和快速开发并不意味着由它开发的程序将失去可维护性或者存在性能问题,它的设计参考了许多协议的实现,比如 FTP,SMTP,HTTP 和各种二进制和基于文本的传统协议,因此 Netty 成功的实现了兼顾快速开发,性能,稳定性,灵活性为一体,不需要为了考虑一方面原因而妥协其他方面。Netty 的应用还是比较广泛的,比如阿里巴巴开源的 Dubbo 和 Sofa-Bolt 框架底层网络通讯都是基于 Netty 来实现的。
|
8天前
|
监控 Java 测试技术
拆帧神器:深度解读Netty中的DelimiterBasedFrameDecoder()
拆帧神器:深度解读Netty中的DelimiterBasedFrameDecoder()
51 0
|
8天前
|
消息中间件 缓存 Java
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
108 0
|
8天前
|
Java Maven
Netty | 属于你的第一款Netty应用程序 🚀
Netty | 属于你的第一款Netty应用程序 🚀
41 0
|
8天前
|
缓存 Java 数据挖掘
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty(一)
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
97 0
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty(一)
|
8天前
|
消息中间件 缓存 Java
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty(二)
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
120 1
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty(二)
|
8天前
|
消息中间件 编解码 Java
京东T8全面详解Java开源框架,透彻剖析尽在《Netty权威指南》
随着大规模分布式系统、大数据和流式计算框架的兴起,基于Java来构建这些系统已经成为主流,NIO编程和NIO框架在此期间得到了大规模的商用。在互联网领域,阿里的分布式服务框架Dubbo、RocketMQ,大数据的基础序列化和通信框架Avro, 以及很多开源的软件都已经开始使用Netty来构建高性能、分布式通信能力,Netty社区的活跃度也名列前茅。
|
7月前
|
存储 前端开发 Java
Netty 爱好者必看!一文详解 ChannelHandler 家族,助你快速掌握 Netty 开发技巧!
Netty 爱好者必看!一文详解 ChannelHandler 家族,助你快速掌握 Netty 开发技巧!
142 0
|
10月前
|
编解码 缓存 网络协议
太厉害了!分享一份京东T9大牛私藏文档:从NIO一直学到Netty
Netty就是基于NIO的网络(Socket)客户端服务端实现框架,它简化了TCP/UDP客户端服务端编程,开发人员不再关注底层的Socket读取和写入,而且Netty提供了不少的handler(如http、mqtt、redis协议等)实现,简化了基于网络协议的编程复杂度。
太厉害了!分享一份京东T9大牛私藏文档:从NIO一直学到Netty