0

我们有一个发送 protobuf 的通信通道。为了能够发送不止一种类型的 protobuf,我们双重序列化:

message Coprolite {
    enum Bezoar {
        KBezoarUndef = 0;
        KBezoarFriedEggs = 1;
        KBezoarHam = 2;
    }
    Bezoar payload_type = 1;
    bytes payload = 2;
}

如果我有一个FriedEggsprotobuf,我将其序列化,将其分配给 Coprolite 的有效负载,将 payload_type 设置为 KBezoarFriedEggs,序列化 Coprolite,然后将其发送。

收到后,我反序列化,检查我有什么,然后反序列化。

这适用于我们所有的平台。但是,我还没有找到其他人这样做的例子(实际上也没有任何其他方式)。所以这表明我应该征求意见。有没有更好的策略或理由让我对此保持警惕?

4

2 回答 2

2

如果你想避免必须设置payload_type,你可以使用 oneof。Oneof 通过在前面添加标签号来隐式序列化有效负载类型。就像任何其他序列化的字段一样。因此,您必须编写更少的管理代码。

但是,与使用 oneof 相比,您的方法有一个优势。深入了解您的编程语言以及如何在您的平台和 protobuf 库中实现 oneof 和字节数组。实现为联合的 oneof 可能会分配最大嵌套消息大小的内存。因此,根据您的情况,当您发送大量小消息时,动态分配字节数组可能会使用更少的内存,有时只会使用大消息。

于 2020-03-26T12:38:59.787 回答
2

这里有两种常见的方法;最简单的(尤其是当类型可以提前预测时)通常是oneof

message Coprolite {
    oneof payload_type {
         FriedEggs eggs = 1;
         Ham ham = 2;
    }
}

这就像一个有区别的联合,您可以在其中检查嵌入类型。

在某些小众场景中,您可能更喜欢使用Any

于 2020-03-26T13:01:00.533 回答