Protocol buffers 减少protobuf消息大小的最佳实践? < P>我使用C中的客户端的原始Buffnet网络消息向C++中的服务器发送位置/旋转数据(Vistr3,四元数)。

Protocol buffers 减少protobuf消息大小的最佳实践? < P>我使用C中的客户端的原始Buffnet网络消息向C++中的服务器发送位置/旋转数据(Vistr3,四元数)。,protocol-buffers,protobuf-net,Protocol Buffers,Protobuf Net,一开始,我尝试了一种分层的方法,即 Message Vector3 { int32 x = 1; int32 y = 2; int32 z = 3; } Message Transform { Vector3 trackedPos1 = 1; Vector3 trackedPos2 = 2; Vector3 trackedPos3 = 3; } 层次结构越来越大,protobuff消息的开销也随之增加。我可以将这些消息扁平化为单个消息,但不确定它将变得如何可管理 那么,有人知道如何以较低的

一开始,我尝试了一种分层的方法,即

Message Vector3
{ 
int32 x = 1;
int32 y = 2;
int32 z = 3;
}

Message Transform
{
Vector3 trackedPos1 = 1;
Vector3 trackedPos2 = 2;
Vector3 trackedPos3 = 3;
}
层次结构越来越大,protobuff消息的开销也随之增加。我可以将这些消息扁平化为单个消息,但不确定它将变得如何可管理


那么,有人知道如何以较低的开销解决这个问题吗?

可能值得考虑的是,您是否可以重新构造树以利用“压缩数组”——例如,如果您正在通过发送200
Transform
(因此:600
Vector3
和1800
int32

只需发送一个:

repeated int32 data = 1 [packed = true];
这是1800长。在protobuf净额中,这可以处理为:

[ProtoMember(1, IsPacked = true)]
public int[] Data {get;set;}
这避免了:

  • 1800个整数字段头
  • 转换
    实例的200个字段标题
  • 200个长度前缀用于
    转换
    实例
  • 用于
    Vector3
    实例的600个字段头
  • Vector3
    实例的600个长度前缀
相反,只使用一个字段头和一个长度前缀


但是,它需要不同的处理。您必须手动将9个连续值的每个块视为一个转换。

非常感谢!我一直在看教练的比赛,他也做过类似的事情。为了避免重新发送所有非更改数据,位或布尔数组或枚举标志将足以标记我将发送的内容?@T.Zak ah,这是一个完全不同的事情-这与我上面提出的想法不符;这需要根据您的特定场景进行设计。protobuf net支持完全条件序列化(通过
ShouldSerialize*()
模式),但这不是一个“是/否”的问题,所以我不能给出简单的答案
[ProtoMember(1, IsPacked = true)]
public int[] Data {get;set;}