如何使用协议缓冲区的扩展来维护“一般"消息 [英] how to use extensions from protocol buffers to maintain 'general' message

查看:43
本文介绍了如何使用协议缓冲区的扩展来维护“一般"消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的客户端-服务器通信如下所示:有一些所谓的通知,它们是用于交换信息的单独消息.这个想法是,通知是每条消息的公共部分.其实我想这将是消息的类型.类型决定了内容是什么.在 UML 类图中,Annoucement 将是所有其他消息继承的类.

My client-server communication looks like this: there are some so called annoucements which are seperate messages used to exchange information. The idea is that annoucement is the common part of every message. Actually I suppose it will be the type of the message. The type decide what is the content. In UML class diagram Annoucement would be the class all other messages inherit.

我想在两个应用程序之间的通信中实现这个想法,一个用 C++ 编写,另一个用 C# 编写.我想我可以写一条消息,其中包含一个字段,如果消息 (枚举字段) 的类型.与类型相关的所有附加信息都将作为扩展实现.

I want to implement that idea in communication between two applications one written in C++ the other in C#. I thought I could write a message that contain one field with the type if the message (an enum field) . All additional information relevant to the type would be implemented as an extensions.

我找到了一些如何在 C++ 中使用扩展的示例,但是我不知道如何在 C# 中使用它.我知道有接口 IExtensible 和 IExtension(在 protobuf-net 中),但我该如何使用它们?互联网资源在这方面似乎很差.

I have found some examples how to use extensions in C++, however I have no clue how to do it in C#. I know there are interfaces IExtensible and IExtension (in protobuf-net) but how can I use them? Internet resources seem to be poor in the matter.

我想过去在 C# 中的消息曾经被定义为类似于时尚,它们仍然在 C++ 应用程序中定义(使用 proto 文件和 protoc).我可以使用相同的 proto 文件在 C# 中定义消息吗?如何?扩展名会被解释或覆盖吗?

I suppose in the past messages in C# used to be define similiar to fashion that they are still defined in C++ apps (using proto file and protoc). Can I use the same proto file to define the message in C#? How? Will extenions be interpreted or overriden?

如果我可以实现扩展,我会发送一条消息,解析它,检查类型并使用适当的函数来维护它.这对我来说听起来很酷,因为我不必关心我将要阅读的消息的类型 - 在解析之前我不必知道类型.

If I could implement extensions, I would sent a message, parse it, check the type and use approriate function to maintain it. That sounds to me cool because I wouldn't have to take care of the type of the message I was going to read - I don't have to know the type before parsing.

推荐答案

有多种方法可以做到这一点.我不确定实际上扩展是我想要的,但是:

There are a number of ways you could do this. I'm not actually sure extensions is the one I would leap for, but:

在您的消息类型中,您可以为每个子消息设置一组完全定义的字段,即

in your message type, you could have a set of fully defined fields for each sub-message, i.e.

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

您将拥有其中一个子消息对象

where you would have exactly one of the sub-message object

或者,封装更具体的消息中的公共部分:

alternatively, encapsulate the common parts inside the more specific message:

common field type
  {1-n} fields
sub-message 1
  {1} common field type
  {2-m} specific fields

任何一种方法都可以让您反序列化;第二个更棘手,IMO,因为它需要您提前知道类型.唯一方便的方法是为每个前缀添加不同的标识符.我个人更喜欢第一个.然而,这不需要扩展——因为我们提前知道一切.碰巧,第一个也是 protobuf-net 如何实现继承,所以你可以通过类型继承(抽象基本消息类型的 4 个具体子类型)和 [ProtoInclude(...)][ProtoInclude(...)]

Either approach would allow you to deserialize; the second is trickier, IMO, since it requires you to know the type ahead of time. The only convenient way to do that is to prefix each with a different identifier. Personally I prefer the first. This does not, however, require extensions - since we know everything ahead of time. As it happens, the first is also how protobuf-net implements inheritance, so you could do that with type inheritance (4 concrete sub-types of an abstract base message type)and [ProtoInclude(...)]

重新扩展数据;protobuf-net 确实支持,但是正如博客中提到的,这不包括在当前的 v2 测试版中.它很快就到了,但我不得不在某处放一条线.虽然它包含在 v1 (r282) 下载中

Re extension data; protobuf-net does support that, however as mentioned in the blog this is not included in the current v2 beta. It will be there soon, but I had to put a line somewhere. It is included in the v1 (r282) download though

请注意,protobuf-net 只是几个 C#/.NET 实现之一.有线格式相同,但您可能还需要考虑直接移植版本.如果我必须总结差异,我会说protobuf-net 是一个 .NET 序列化程序,恰好是 protobuf;protobuf-csharp-port 是一个 protobuf 序列化程序,恰好是 .NET"——它们都达到了相同的目的,但是protobuf-net 侧重于符合 C#/.NET 的习惯,而端口更侧重于具有相同的 API.当然,两者都应该在这里工作.

Note that protobuf-net is just one of several C#/.NET implementations. The wire format is the same, but you might also want to consider the directly ported version. If I had to summarise the difference I would say "protobuf-net is a .NET serializer that happens to be protobuf; protobuf-csharp-port is a protobuf serializer that happens to be .NET" - they both achieve the same end, but protobuf-net focuses on being idiomatic to C#/.NET where-as the port focuses more on having the same API. Either should work here of course.

这篇关于如何使用协议缓冲区的扩展来维护“一般"消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆