Protobuf 是经过深思熟虑的消息打包方案,它的默认序列化格式没有包含消息的长度与类型,自然有其道理。哪些情况下不需要在 protobuf 序列化得到的字节流中包含消息的长度和(或)类型?我能想到的答案有:
- 如果把消息写入文件,一个文件存一个消息,那么序列化结果中不需要包含长度和类型,因为从文件名和文件长度中可以得知消息的类型与长度。
- 如果把消息写入文件,一个文件存多个消息,那么序列化结果中不需要包含类型,因为文件名就代表了消息的类型。
- 如果把消息存入数据库(或者 NoSQL),以 VARBINARY 字段保存,那么序列化结果中不需要包含长度和类型,因为从字段名和字段长度中可以得知消息的类型与长度。
- 如果把消息以 UDP 方式发生给对方,而且对方一个 UDP port 只接收一种消息类型,那么序列化结果中不需要包含长度和类型,因为从 port 和 UDP packet 长度中可以得知消息的类型与长度。
- 如果把消息以 TCP 短连接方式发给对方,而且对方一个 TCP port 只接收一种消息类型,那么序列化结果中不需要包含长度和类型,因为从 port 和 TCP 字节流长度中可以得知消息的类型与长度。
- 如果把消息以 TCP 长连接方式发给对方,但是对方一个 TCP port 只接收一种消息类型,那么序列化结果中不需要包含类型,因为 port 代表了消息的类型。
- 如果采用 RPC 方式通信,那么只需要告诉对方 method name,对方自然能推断出 Request 和 Response 的消息类型,这些可以由 protoc 生成的 RPC stubs 自动搞定。
对于最后一点,比方说 sudoku.proto 定义为:
service SudokuService { rpc Solve (SudokuRequest) returns (SudokuResponse); }
那么 RPC method Sudoku.Solve 对应的请求和响应分别是 SudokuRequest 和 SudokuResponse。在发送 RPC 请求的时候,不需要包含 SudokuRequest 的类型,只需要发送 method name Sudoku.Solve,对方自知道应该按照 SudokuRequest 来解析(parse)请求。这个例子来自我的半成品项目 evproto,见 http://blog.csdn.net/Solstice/archive/2010/04/17/5497699.aspx 。
对于上述这些情况,如果 protobuf 无条件地把长度和类型放到序列化的字节串中,只会浪费网络带宽和存储。可见 protobuf 默认不发送长度和类型是正确的决定。Protobuf 为消息格式的设计树立了典范,哪些该自己搞定,哪些留给外部系统去解决,这些都考虑得很清楚。
只有在使用 TCP 长连接,且在一个连接上传递不止一种消息的情况下(比方同时发 Heartbeat 和 Request/Response),才需要我前文提到的那种打包方案。(为什么要在一个连接上同时发 Heartbeat 和业务消息?请见陈硕《分布式系统的工程化开发方法》 p.51 心跳协议的设计。)这时候我们需要一个分发器 dispatcher,把不同类型的消息分给各个消息处理函数,这正是本文的主题之一。
相关推荐
Unity 中使用Protobuf进行序列化和反序列化的Demo
大数据场景下序列化和反序列化技术,谷歌提供技术 protobuf-jetbrains-plugin-0.13.0.zip
protobuf常用序列化和反序列化API,相关教程:http://blog.csdn.net/tennysonsky/article/details/73920767
Google Protobuf基于Qt开发序列化与反序列化用QUdpSocket传输并显示。实例。 具体可查看了解:https://blog.csdn.net/automoblie0/article/details/101363526
protocolbuffer是google 的一种数据交换的格式,它独立于语言,独立于平台。 google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。
在Unity5中Protobuf的序列化和反序列化,解决了因Android和IOS平台的不同而不能解析的问题。
ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化示例代码.rar
ros2使用自建类型编译,订阅以及发布的demo,并且包括和protobuf互转的使用方式. 自建类型为序列化数据{uint32 size, uint8 data[] }
自己实现的protobuf 压缩类,并能序列化反序列化
C#中使用二进制和ProtoBuf分别进行序列化、反序列化、压缩、解压缩对比测试示例源码
[ProtoContract] //声明这个类能被序列化 public class UserData { //声明每一个需要被序列化的成员,编号从1开始 [ProtoMember(1)] public int id; [ProtoMember(2)] public string name; [ProtoMember...
类似 google protobuf,用于序列化/反序列化 c 结构体。支持序列化为 xml/json/binary 3 种格式。
netty protobuf序列化对象 推送 android客户端,压缩包中有两个工程。服务,客户端。
通过proto工具编译的message结构被序列化,无法看出proto组织结构,通过这里的工具实现反序列化,清楚看到原messgae结构。注意:第六步运行的脚本操作过程按照其中的pdf文件最后的dos命令进行操作。
C# Protobuf-Net 序列化
附带proto的调用命令跟测试的proto文档
NULL 博文链接:https://luoshi0801.iteye.com/blog/1828035
v1.1 更新内容。1. 增加错误信息。2. 修改数组为proto3储存方式。@wlp。
protobuf序列化JAVA使用的JAR包,版本:3.15。直接下载,不用编译,这玩意儿编译还是很麻烦。
Python调用序列化数据工具Protocol Buffers——protobuf https://xercis.blog.csdn.net/article/details/109204030