Protobuf 多对象序列化顺序?

Posted

技术标签:

【中文标题】Protobuf 多对象序列化顺序?【英文标题】:Protobuf multiple object serialization order? 【发布时间】:2018-06-10 18:11:26 【问题描述】:

我正在构建一个套接字服务器 - 客户端应用程序,并且我正在使用 protobuf-net 序列化/反序列化从一个发送到另一个的数据。现在我正在发送一个对象并在接收器上,根据我知道我想接收和反序列化的数据包的标头。我想知道是否可以将多个对象作为具有不同类型的 object[] 发送,序列化和反序列化与数组上对象的顺序无关?我假设这意味着数组上的每个对象都应该有一个以某种方式序列化的类型标识符,所以反序列化我知道它是哪个对象。另外,一个变量标识符(如变量名),因此可以区分具有相同类型的多个对象。

我认为最简单的方法是始终将我的数据包装在一个对象中,并将我的所有数据作为属性。只是想知道这是否可能以某种方式使我的代码更容易不必创建所有这些包装类。

【问题讨论】:

【参考方案1】:

object 很尴尬,因为引擎无法知道您的意图。 protobuf-net 中嵌入了一些动态类型的东西,它嵌入了 AQN 类型,但坦率地说,这是一个巨大的 hack。到目前为止,您最好的选择是将自己限制在某些有限的继承模型中。例如:

[ProtoContract]
[ProtoInclude(1, typeof(Foo)]
[ProtoInclude(2, typeof(Bar)]
public class MessageBase 

[ProtoContract]
public class Foo : MessageBase 

(同样Bar

然后发送MessageBase[] 并使用Deserialize(或DeserializeWithLengthPrefix)指定<MessageBase>。每条消息都将作为正确的类型发送和检索,允许使用多态性或新的switch 模式匹配来路由传入消息,并且没有歧义。

在幕后,它是这样实现的(在 .proto 中):

message MessageBase 
    oneof ActualType 
        Foo foo = 1;
        Bar bar = 2;
    

message Foo 
message Bar 

【讨论】:

谢谢 Marc,我正在尝试为我的发送/接收构建一个类似于 Web 开发的框架,其中控制器操作中的参数不需要具有特定的顺序。所以我的接收器有一个Action(int userId, ComplexObj data, int age) 能够从调用者PacketSend(actionRoute, params object[] objs) 发送,然后在接收器上反序列化这些参数并通过MethodInfo.Invoke() 将它们分配给方法我不确定这是否可以通过protobuf 实现反序列化如果调用者更改顺序,我将无法区分 userId 和年龄。 所以我认为我对 protobuf 的唯一选择是创建一个包装类,其中这些参数是属性,然后更改我的 PacketSend(actionRoute, object obj) 将其序列化并使用包装类进行反序列化收件人。基本上将自己限制为每个动作 1 个参数。 @Nauzet 本质上就是 protobuf 定义服务的方式,所以......这可能是要走的路

以上是关于Protobuf 多对象序列化顺序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能使用 ProtoBuf-Net 正确反序列化我的对象?

使用 ØMQ/ZMQ 序列化 Protobuf 对象并发送

对象(通用)的 Protobuf-net 序列化抛出错误没有为类型定义序列化程序:System.Object

使用非标准构造函数序列化和反序列化对象 - protobuf-net

protobuf-net 是不是适合序列化任意对象/域模型?

如何使用 Protobuf.net C# 序列化自定义对象基础属性