我的客户端-服务器通信是这样的:有一些所谓的公告,它们是用于交换信息的单独消息。这个想法是公告是每条消息的公共(public)部分。其实我想这将是消息的类型。类型决定内容是什么。在 UML 类图中,Annoucement 将是所有其他消息继承的类。
我想在两个应用程序之间的通信中实现这个想法,一个用 C++ 编写,另一个用 C# 编写。我想我可以写一条消息,其中包含一个类型为 if the message (an enum field) 的字段。与该类型相关的所有附加信息都将作为扩展实现。
我找到了一些如何在 C++ 中使用扩展的示例,但是我不知道如何在 C# 中执行此操作。我知道有接口(interface) IExtensible 和 IExtension(在 protobuf-net 中)但我该如何使用它们?互联网资源似乎在这方面很差。
我想过去 C# 中的消息定义类似于时尚,它们仍然在 C++ 应用程序中定义(使用 proto 文件和 protoc)。我可以使用相同的原型(prototype)文件在 C# 中定义消息吗?如何?扩展会被解释还是被覆盖?
如果我可以实现扩展,我会发送一条消息,解析它,检查类型并使用适当的函数来维护它。这对我来说听起来很酷,因为我不必关心我将要阅读的消息的类型——我不必在解析之前知道类型。
最佳答案
有多种方法可以做到这一点。我不是实际上确定扩展是我想要的,但是:
在您的消息类型中,您可以为每个子消息设置一组完全定义的字段,即
base-message
{1-5} common fields
{optional 20} sub-message 1
{optional 21} sub-message 2
{optional 22} sub-message 3
{optional 23} sub-message 4
sub-message 1
{1-n} specific fields
您将恰好拥有其中一个子消息对象
或者,封装更具体消息中的公共(public)部分:
common field type
{1-n} fields
sub-message 1
{1} common field type
{2-m} specific fields
这两种方法都可以让你反序列化;第二个更棘手,IMO,因为它需要你提前知道类型。唯一方便的方法是为每个前缀加上不同的标识符。我个人更喜欢第一种。然而,这并不需要扩展——因为我们提前知道了一切。碰巧的是,第一个也是 protobuf-net 如何实现继承,因此您可以使用类型继承(抽象基本消息类型的 4 个具体子类型)和 [ProtoInclude(...)]
重新扩展数据; protobuf-net 确实支持,但是as mentioned in the blog这不包括在当前的 v2 测试版中。它很快就会出现,但我不得不在某个地方放一条线。尽管它包含在 v1 (r282) 下载中
请注意,protobuf-net 只是几个 C#/.NET 实现之一。有线格式相同,但您可能还需要考虑 directly ported version .如果我必须总结差异,我会说“protobuf-net 是一个恰好是 protobuf 的 .NET 序列化程序;protobuf-csharp-port 是一个恰好是 .NET 的 protobuf 序列化程序”——它们都达到了相同的目的,但是protobuf-net 侧重于 C#/.NET 的惯用性,因为端口更侧重于拥有相同的 API。当然,两者都应该在这里工作。
关于c# - 如何使用 Protocol Buffer 的扩展来维护 'general' 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6243362/