c# - 独立于平台的 protobuf 套接字协议(protocol)——我会收到什么消息?

标签 c# sockets network-protocols protocol-buffers protobuf-net

我正准备编写一个与平台无关的套接字协议(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/

相关文章:

c# - 本地序列不能用于查询运算符的 LINQ to SQL 实现,但 Contains() 运算符除外

linux - 多节点连接管理

python - 如何强制操作系统使用 python 释放端口

iphone - 如何使用 ASIHTTPRequest 发送删除请求?

c# - Sharepoint 访问请求 "Permission"代码

c# - 在 ASP.NET Core 2.0 中将 DataTable 转换为 IEnumerable<T>

c++ linux accept()在套接字关闭后阻塞

java - 如何用 Java 确定我的路由器/网关的 IP?

java - 从套接字读取位而不是整数

c# - 来自另一个类库的基本 Controller 在 web api 中不起作用