在新版Unity中使用Protobuf以及使用Google.Protobuf.WellKnownTypes中的Duration Timestamp

总的来说,就是手写.proto文件后,用CMD命令行运行protoc.exe编译器,进入.proto文件路径生成C#文件,再把C#文件放到Unity项目中使用。

准备编译器:

编译器是用来将.proto文件编译成相应语音脚本的工具, 编译器可以直接从GitHub上下载也可以选择自己使用工具生成。
GitHub下载 (Git地址 https://github.com/google/protobuf/releases), 下载 对应的protobuf包 (如 protoc-3.9.1-win64.zip), 在bin文件夹下有对应得 protoc.exe 编译器

编写.proto文件:

syntax = "proto3";

package namespace.packagename;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

message classname{
string name=1;
google.protobuf.Duration Delta=2;
google.protobuf.Timestamp lastTime=3;
}

!注意Duration 和Timestamp 的大小写!

编译.CS文件:

E:\OtherProjects\protoc\bin>protoc.exe --proto_path=./ classname.proto --csharp_out=./generate

!注意classname前面要加空格,否则报错“missing input file”

更多proto语法,命令: https://developers.google.com/protocol-buffers/docs/proto3

将CS文件拷入unity

准备DLL文件:

1,从GitHub上下载protobuf源码 (源码链接:https://github.com/google/protobuf)我下的是protobuf-3.9.1
2,打开工程目录下 csharp/src/Google.Protobuf.sln 文件。 PS:在下用的VS2017打开的
3,生成Google.Protobuf得到Google.Protobuf.dll文件 (netstandard1.0版)

4,拷入unity

测试:

类似下列代码进行测试(参考自 https://www.jianshu.com/p/b135676dbe8d):

using UnityEngine;
using Protobuf;            //应用CS文件的命名空间 (.proto文件中的 package 值)
using Google.Protobuf;     //引用DLL
using Google.Protobuf.WellKnownTypes;

public class Test : MonoBehaviour {

   void Start()
   {
       //新建一个Person对象,并赋值
       Person ac = new Person();
        ac.Proj = "ts1";
        ac.Delta = Duration.FromTimeSpan(new TimeSpan(314));
        ac.LastTime = Timestamp.FromDateTime(DateTime.Now.ToUniversalTime());//ArgumentException: Conversion from DateTime to Timestamp requires the DateTime kind to be Utc

        //将对象转换成字节数组
        byte[] databytes = ac.ToByteArray();

        //将字节数据的数据还原到对象中
        IMessage IMperson = new Person();
        Person p1 = new Person();
        p1 = (Person)IMperson.Descriptor.Parser.ParseFrom(databytes);

        //输出测试
        Debug.Log(p1.Proj);
        Debug.Log(p1.FirstTime);//默认值为null
        Debug.Log(p1.LastTime.ToDateTime().ToLocalTime());
        Debug.Log(p1.Delta);
   }
}

 

<think>嗯,用户之前问过除了ASN.1和Protobuf之外还有哪些常用的编码方式,我之前已经给出了一个比较详细的回答。现在用户再次提问,引用了站内的一些资料,但主要是关于Protobuf的,所以可能需要确认用户是否已经了解这些信息,还是希望更深入地了解其他编码方式。 首先,用户明确提到“除了ASN和Protobuf之外的常用二进制编码方式”,所以需要排除这两个,重点放在其他选项上。之前的回答已经提到了MessagePack、Avro、Thrift、CBOR、FlatBuffers等,可能需要再次整理这些内容,但根据用户的新引用,可能需要更详细或调整结构。 用户提供的引用中提到了Protobuf的优势和缺点,比如二进制格式、跨语言支持、性能等,这可能暗示用户对高效、跨平台的编码方式感兴趣。同时引用2提到了WCF的编码格式,包括二进制、文本、MTOM、JSON和POX,这可能与用户的问题相关,但用户明确要二进制,所以需要关注其中的二进制相关部分。 用户还提到序列化的必要性,比如解决字节序、平台差异、语言差异的问题,所以在回答其他二进制编码方式时,需要强调它们如何处理这些问题,比如是否内置字节序处理,是否支持跨语言等。 可能需要检查之前的回答是否覆盖了所有主要的二进制编码方式,或者是否有遗漏。例如,是否提到BSON、Cap'n Proto等。或者是否需要补充更多细节,比如每种编码的具体应用场景、优缺点对比等。 用户引用的资料3和4提到Protobuf的高效和兼容性,所以在介绍其他编码方式时,需要对比说明它们的性能、体积、兼容性如何,是否在某些方面优于Protobuf,或者适用于不同场景。 另外,用户引用5提到Protobuf在C++支持上的问题,比如注释丢失,消息名称不同导致不支持相同内容,这可能暗示用户关心不同编码方式的工具链支持、生成的代码质量等,所以在回答其他编码方式时,可以提到它们的工具支持情况,生成代码的可读性,跨语言支持是否完善等。 可能需要将回答结构优化,比如分为结构化文本编码、高性能二进制编码、专用场景编码等,但用户这次可能更关注二进制,所以需要调整结构,突出二进制部分,比如直接列出二进制编码方式,详细说明每个的特点,应用场景,优缺点,引用中的相关点等。 另外,用户引用2提到了WCF的二进制编码,这可能是一个点,虽然它可能属于微软特定的技术,但可以简要提及,比如.NET的BinaryFormatter,不过这可能不是跨平台的,所以是否值得推荐需要考量。 需要确保回答中的每个编码方式都有明确的例子,技术特点,应用场景,并且引用相关的资料,比如引用中提到的JSON在WCF中的应用,可以关联到MessagePack或BSON作为其二进制版本。 可能需要检查是否有遗漏的编码方式,比如Apache Arrow,Cap'n Proto,或者某些行业专用的编码方式,如金融领域的FAST协议等,但需要确认是否常用。 最后,确保回答符合用户的要求,使用中文,结构清晰,分点列出,正确使用LaTeX格式,引用标识,以及生成相关问题。</think>#### 常用二进制编码方式(除ASN.1与Protobuf外) --- ##### 一、通用二进制编码 1. **MessagePack** - **核心特性**: - 兼容JSON语义的二进制格式,采用类型标记+紧凑字节布局,体积比JSON小30%-50% - 直接支持基础类型(整数、浮点数、字符串)和复合结构(数组、Map) - 支持跨语言(Python/Java/C++等),无需预定义Schema ```python # Python序列化示例 import msgpack data = {"sensor_id": 1001, "readings": [23.5, 24.0, 22.8]} binary_data = msgpack.packb(data) # 输出紧凑二进制流 ``` - **优势场景**: - 实时消息系统(如Redis Pub/Sub) - 物联网设备数据传输(低带宽需求) - 游戏网络协议(快速序列化/反序列化)[^2] 2. **Apache Avro** - **核心特性**: - **Schema驱动**:序列化数据必须绑定Avro Schema文件(JSON格式定义) - **无类型标记**:二进制流仅存储数据值,依赖Schema解析,体积极致优化 - **动态模式演进**:支持字段增删改(向后/向前兼容) ```json // Avro Schema定义 { "type": "record", "name": "User", "fields": [ {"name": "id", "type": "int"}, {"name": "name", "type": "string"} ] } ``` - **优势场景**: - Hadoop生态数据存储(如HDFS文件格式) - Kafka流式数据处理(Schema Registry集成)[^3] 3. **Apache Thrift(Binary Protocol)** - **核心特性**: - 通过IDL(接口定义语言)生成多语言代码,强制类型约束 - 提供二进制、压缩二进制等多种编码选项 - 支持RPC通信框架集成(如服务端/客户端桩代码生成) ```thrift // Thrift IDL定义 struct Location { 1: required double latitude, 2: required double longitude, 3: optional i16 altitude } ``` - **优势场景**: - 跨语言微服务通信(如Facebook内部系统) - 高吞吐量日志采集(压缩二进制优化)[^3] --- ##### 二、专用优化编码 4. **FlatBuffers** - **核心特性**: - **零解析开销**:二进制数据直接映射到内存,支持随机访问字段 - **内存高效**:数据存储无需额外内存分配(对比Protobuf减少30%内存占用) - 支持Schema演进(通过字段deprecated标记) ```cpp // FlatBuffers定义 table Weapon { name: string; damage: short; } ``` - **优势场景**: - 游戏引擎数据存储(如Unity资源文件) - 移动端高性能渲染(直接GPU内存映射)[^2] 5. **CBOR(Concise Binary Object Representation)** - **核心特性**: - 兼容JSON数据模型的二进制表示,支持自描述数据标签 - 内置日期、正则表达式等扩展类型,适合语义化数据 - 规范定义于RFC 8949,被IETF标准化 ```python # CBOR编码示例(Python cbor2库) import cbor2 data = {"timestamp": 1690000000, "value": 37.6} cbor_data = cbor2.dumps(data) # 输出带类型标记的二进制 ``` - **优势场景**: - IoT设备通信(CoAP协议标准编码) - 数字证书扩展字段(如X.509证书自定义属性)[^1] 6. **Cap'n Proto** - **核心特性**: - 数据编码与内存布局完全一致,实现**零拷贝解析** - 支持RPC框架集成,性能优于Protobuf - 允许数据段随机读写(类似数据库游标操作) ```capnp # Cap'n Proto定义 struct Person { id @0 :UInt32; name @1 :Text; email @2 :Text; } ``` - **优势场景**: - 高频交易系统(纳秒级延迟需求) - 大规模分布式数据库(LevelDB替代方案) --- ##### 三、对比与选型 | 编码方式 | 核心优势 | 典型劣势 | 适用场景 | |----------------|-----------------------------|----------------------------|-------------------------| | MessagePack | 轻量快速,无Schema约束 | 无模式校验,数据安全性低 | 临时数据传输、配置存储 | | Avro | Schema演进,大数据生态集成 | 依赖外部Schema文件 | 数据湖/流处理管道 | | Thrift(Binary) | 强类型RPC集成,多语言支持 | IDL学习成本高 | 企业级微服务架构 | | FlatBuffers | 零解析延迟,内存高效 | 数据不可变,修改成本高 | 游戏/移动端资源加载 | | CBOR | 自描述标签,IETF标准化 | 工具链成熟度较低 | 嵌入式设备、安全协议 | | Cap'n Proto | 零拷贝,极致性能 | 社区生态较小 | 超低延迟系统 | --- ##### 四、技术决策建议 1. **优先考虑数据体积**: - 选择Avro(Schema压缩优化)或MessagePack(通用场景) 2. **要求最低延迟**: - 采用FlatBuffers(直接内存访问)或Cap'n Proto(零拷贝) 3. **强类型安全需求**: - 使用Thrift(IDL强约束)或Avro(Schema校验) 4. **跨平台嵌入式设备**: - CBOR(自描述+标准化)或自定义TLV协议(极致精简) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值