我正准备编写一个与平台无关的套接字协议(protocol)。经过一些初步研究,protobuf 似乎是可行的方法。我是 protobuf 的新手,我似乎无法弄清楚一个具体问题。
我的要求是:
完全独立于平台的客户端;
C#服务器;
异步消息通信;
从
.proto
文件开始工作(因此不会从现有类推断);必须能够在服务器/客户端事先不知道预期的消息类型的情况下发送消息。
我已经找到了 (De)SerializeWithLengthPrefix
方法,它们是一个开始。 我想不通的是,如果我事先不知道类型,如何接收消息。
我已经看到 protobuf-net 支持继承并且可以检测消息的类型,因此对于 protobuf-net,从一个公共(public)基类型继承所有消息是可行的。 但是,这不是平台独立的,我正在寻找一种独立于平台的方式来做到这一点。
所以我的问题是:我如何发送我的消息,以便任何客户端都可以在不知道类型的情况下反序列化它们?
最佳答案
如果需要处理多个不同类型的消息:
只需为每种不同类型的消息关联一个唯一编号,并用作消息的前缀;您可以使用重载的 SerializeWithLengthPrefix
方法的可选整数参数轻松完成此操作。客户端必须预处理这个前缀(或者它可以在 protobuf-net 中由 Serializer.NonGeneric
处理,它有一个反序列化方法,提供从这个前缀号获取类型的回调) .
如果要求使用完全未知的数据:
根据您的要求,我怀疑 Jon's port会更合适;因为您的重点是平台独立性和 .proto,而不是推理(protobuf-net 擅长的地方)或其他 .NET 特定的扩展/实用程序。
请注意,虽然 .proto 可以(通过 protoc)编译为常规 protobuf 流,但在接收方处理完全外部数据是……不规则的。它可能可以通过将所有内容都视为扩展或通过使用编码流来完成,但是......
在评论中编辑以下讨论:
这里的简单模式可以是:
message BaseMessage {
optional SomeMessage someMessage = 1;
optional SomeOtherMessage someOtherMessage = 2;
optional SomeThirdMessage someThirdMessage = 3;
}
message SomeMessage {...}
message SomeOtherMessage {...}
message SomeThirdMessage {...}
(如果有帮助,您可以选择添加鉴别器)
这实际上是 本质上 protobuf-net 如何处理继承,但很容易从其他客户端表示,并自动处理所有内容,例如子消息的长度。
关于c# - 独立于平台的 protobuf 套接字协议(protocol)——我会收到什么消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4094749/