平台独立的 protobuf 套接字协议 - 我会收到什么消息?
我正准备编写一个独立于平台的套接字协议。经过一些初步研究,protobuf 似乎是可行的方法。我是 protobuf 的新手,我似乎无法弄清楚一个具体问题。
我的要求是:
完全独立于平台的客户端;
C# 服务器;
异步消息通信;
从
.proto
文件工作(因此不会从现有类推断);必须能够在服务器/客户端事先不知道需要哪种消息类型的情况下发送消息。
我已经找到了 (De)SerializeWithLengthPrefix
方法,它们是一个开始。 我不知道的是,如果我事先不知道消息的类型,如何接收消息。
我已经看到protobuf-net支持继承并且可以检测消息的类型,所以对于 protobuf-net,从公共基本类型继承所有消息是可行的。 但是,这不是独立于平台的,我正在寻找一种独立于平台的方式来执行此操作。
所以我的问题是:如何发送消息,以便任何客户端都可以在不知情的情况下反序列化它们前面的类型?
I am preparing to write a platform independent socket protocol. After some initial research protobuf seems the way to go. I am new to protobuf and I can't seem to figure out one specific issue.
My requirements are:
Completely platform independent client;
C# server;
Async message communication;
Work from a
.proto
file (so no inference from existing classes);Must be able to send messages without the server/client knowing up front which message type to expect.
I have already found the (De)SerializeWithLengthPrefix
methods, and they are a start. What I can't figure out is how to receive a message if I do not know the type up front.
I have already seen that protobuf-net supports inheritance and can detect the type of the message, so for protobuf-net, inheriting all messages from a common base type would work. However, this is not platform independent and I am looking for a platform independent way of doing this.
So my question is: how do I send my messages so that any client can deserialize them without knowing the type up front?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果需要处理多个不同类型的消息:
只需将每个不同类型的消息关联一个唯一的编号,并用作消息的前缀即可;您可以使用重载的
SerializeWithLengthPrefix
方法的可选整数参数轻松完成此操作。客户端必须预处理此前缀(或者可以通过Serializer.NonGeneric
在 protobuf-net 中处理,它有一个反序列化方法,提供用于从该前缀编号获取类型的回调) 。如果要求是处理完全未知的数据:
鉴于您的要求,我怀疑 Jon 的端口 会更合适;因为您的重点是平台独立性和 .proto,而不是推理(protobuf-net 擅长的地方)或其他 .NET 特定扩展/实用程序。
请注意,虽然 .proto 可以(通过 protoc)编译为常规 protobuf 流,但在接收器上处理完全外部的数据是......不规则的。它可能可以通过将所有内容视为扩展或使用编码流来完成,但是......
编辑评论中的以下讨论:
这里的简单模式可以很简单:(
您可以选择添加一个鉴别器,如果有帮助的话)
这是实际上,protobuf-net 本质上是如何处理继承的,但很容易从其他客户端表示出来,并自动处理子消息长度等所有内容。
If the requirement is to work with multiple messages of different types:
Just associate a unique number with each different type of message, and use as a prefix to the message; you can do this trivially with the optional integer parameter to the overloaded
SerializeWithLengthPrefix
method. The client would have to pre-process this prefix (or it can be handled within protobuf-net bySerializer.NonGeneric
, which has a deserialization method that provides a callback for obtaining the type from this prefix number).If the requirement is to work with completely unknown data:
Given you requirements, I suspect Jon's port would be a better fit; since your emphasis is on platform independence and .proto, and not on inference (where protobuf-net excels) or other .NET specific extensions / utilities.
Note that while a .proto can be compiled (via protoc) to a regular protobuf stream, working with entirely foreign data at the receiver is... irregular. It can probably be done by treating everything as extensions or by working with the coded streams, but...
Edit following discussion in comments:
A simple schema here could be simply:
(you could optionally add a discriminator, if that helps)
This is actually essentially how protobuf-net treats inheritance, but is easily represented from other clients, and handles everything like lengths of sub-messages automatically.