工具篇:protobuf序列化
Protobuf 初识
什么是Protobuf
Google Protocol Buffers(简单Protobuf或PB) 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关 、可扩展的序列化结构数据格式 。目前,几乎支持所有主流编程语言 。
他和xml、json一样,都属于数据标记语言。
Protobuf优势
- 序列化与反序列化速度极快。
- 与语言及平台无关,兼容性好,通过 proto文件生成多种语言文件 => 实现 服务端、客户端之间 跨语言平台的数据转换。
- 数据高度压缩 => 占用空间少,节省带宽。
Protobuf使用
Protobuf对比C#常规序列化
标签不同,常规只需要对类打上[Serializable]
,而Protobuf需要对类打上[ProtoContract]
,再对属性打上[ProtoMember(1)]
,中间的数字是tag对应一个属性。
调用不同,常规需要 Stream 配合 BinaryFormatter 来实现,protobuf的话是 Stream 配合 ProtoBuf.Serializer:
1 | // ProtoBuf Serialize |
字节量大幅优化,对2种bytes都进行输出,简单使用能直接缩10倍以上:
需求提纯
那么最后,我们要做什么?
- 使用protobuf通信,且自动化解决最基础的打标签方式,因为那太过繁琐。
- 需要支持多平台,所以直接排除
[Serializable]
。
Protobuf 网络通信解决方案
1.制定协议
2.获取工具
在 .net专用版本 作者Marc Gravell(本篇使用) 中,编译源码获取 protoc.exe 和 压缩包中的 protogen.exe 两个文件。
3.生成代码
定义文件 .proto
相当于把之前C#实现的整个协议重写一遍。建议使用IDE VSCode来检查语法。
syntax - 使用proto package - 定义头文件名
message - 类 enum - 枚举类
required - 必须的 optional - 非必须的 repeated - 重复的,用于List
1 | syntax = "proto2"; |
使用工具 protogen.exe
protoc.exe也可以用于生成c#代码,但是数据更多,所以直接使用protogen.exe。
- cmd进入对应路径。
- 可以使用
protogen -h
命令来获取命令help。 - 输入指令
.\soft\protogen.exe --csharp_out=.\ .\NetProtocol.proto
来生成代码。
指令解析:
- .\soft\protogen.exe 工具位置
- –csharp_out=.\ 输出位置
- .\NetProtocol.proto 文件位置
4.对比cs和proto协议区别
proto中的package转换成 namespace
。
为每一个class和enum打上标签 [global::ProtoBuf.ProtoContract()]
。括号里面是反射时识别的类名,不写就直接是类名。
为每一个属性打上标签 [global::ProtoBuf.ProtoMember(1)]
。括号里是proto文件中定义的数字。
开源地址
我的可视化GUI
我将集成这些功能到自己做的wpf工具中(.proto生成.cs)。
我的UDP C-S服务器通信解决方案
基于KCP优化UDP传输可靠性的 Unity/.net Client - .net Server 通信解决方案,可以选择proto协议,内有案例。