【问题标题】:Protocol Buffers - Reading header (nested message) common across all messages协议缓冲区 - 读取所有消息通用的标头(嵌套消息)
【发布时间】:2012-11-13 14:41:07
【问题描述】:

我目前正在评估项目中使用的协议缓冲区(目前还没有编写代码)。我不清楚的一件事是您将如何阅读编码消息的一部分,例如说我有一个共同的标头:

message Header {
  required uint16 msg_type = 1;
  required uint16 length = 2;
}

假设我将多个不同的消息传递到一个队列。消费者如何计算出每条消息要读取多少数据以及应该构造什么消息类型?

【问题讨论】:

  • 我之前没有提供帮助,但我学到了很多-谢谢这个问题

标签: c++ protocol-buffers


【解决方案1】:

这里应该不需要Header 消息;最常见的方法是遵循“流式传输”建议from here。在其中,您可以将其视为相同的union type 消息序列,或者(我的偏好)在编写时,而不是仅在每个之前编写长度前缀,包括一个指示消息类型的 varint then 长度(作为变量)。指示消息类型的数字是您发明的任意映射,因此 1 = Foo、2 = Bar、3 = Blap 等)。如果您将消息类型左移 3 位然后“或”2,那么它也将是一个格式良好的 protobuf 流本身,与 repeated YourUnionType 100% 相同。

基本上,这与this answer 完全相同,但不是每次都是字段 1,而是每个消息类型的数字都不同。大多数实现都有一个读取器/写入器 API,可以读取和写入原始变量,并限制读取器 API 的长度。一些实现具有帮助机制来直接支持异构消息流(基本上,为您完成上述所有工作)。

【讨论】:

  • 我查看了 union 的东西,看起来不错,符合我的要求。为了确保我得到这个正确的解决方案,最终的解决方案将有一个带有required uint16 msg_typerequired uint16 msg_len 和一组optional 消息声明的“包装器”类。然后我可以将我所有的消息定义为单独的消息,而不用关心长度和类型?
  • @Graeme 完全取决于您的意思;p 是的,带有 repeated(某种联合类型)的包装器可以正常工作,但最好像 Bart 的回答中那样使用 repeated ContainerMessage。我想不出 msg_type 和 msg_len 有用的场景,因为基本上已经处理好了
  • 感谢 Marc,非常有帮助,非常感谢。
【解决方案2】:

在最近的一个项目中,我使用了这样的协议缓冲区:

我们有一个“容器”消息,其中包含所有实际消息作为可选成员:

message ContainerMessage {
    optional Message1 message_1 = 1;
    optional Message2 message_2 = 2;
    //...
    optional MessageN message_N = N;
}

在应用程序中,您可以只使用ContainerMessage 作为真实消息的可区分联合。

在应用程序之间,我们对ContainerMessage进行序列化/反序列化并发送序列化内容,前缀为包含序列化内容长度的简单标头。

【讨论】:

    【解决方案3】:

    这取决于您使用的协议。

    请注意,例如许多协议通过串行接口进行,在那里您可能有额外的行来告诉消息何时开始和停止。

    通常,消息在消息开始后会有一个固定偏移量的长度。

    在其他情况下,您可能需要逐个元素地解析消息,以找出剩余的消息量。所以嵌入在消息中的字符串可能是固定长度的,或者在开头有长度,或者可能有 \0 作为结束标记。

    大多数情况下,当您将消息存储在队列中以供进一步处理时,您会希望添加更多信息以使您的生活更轻松 - 例如,当您有一个额外的信号告诉您消息何时停止时,您可能会存储消息内部有它的长度。

    【讨论】:

    • protobuf 是一个定义明确的单一协议,但是......这个答案是专门针对 protobuf 的吗?还是这是在谈论一般情况?
    • @Caribou:是的,很抱歉没听明白。谢谢你告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    相关资源
    最近更新 更多