[英]Protocol buffers detect type from raw message
是否可以检测原始协议缓冲区消息的类型(在byte []中)
我有一种情况,端点可以接收不同的消息,我需要能够检测类型,然后才能反序列化它。
我正在使用protobuf-net
您不能孤立地检测类型,因为protobuf规范不会为此向流添加任何数据; 但是,根据具体情况,有很多方法可以简化:
在原始TCP流的情况下,最后一种方法实际上非常有价值; 这与导线类型相同,但具有不同的实现; 通过预先确定1 = Foo,2 = Bar等(与联合类型方法完全相同),您可以使用SerializeWithLengthPrefix
进行写入(将1/2 / etc指定为字段编号),以及非泛型要读取TryDeserializeWithLengthPrefix
(这是在v1 API中的Serializer.NonGeneric下,或者在v2 API中的TypeModel下),您可以提供一个类型映射,将数字解析回类型,从而反序列化正确的类型。 并预先解决“为什么这对TCP流有用?” - 因为:在正在进行的TCP流中, 无论如何都需要使用WithLengthPrefix
方法,以避免过度读取流; 所以你不妨免费获得类型标识符!
摘要:
一个典型的选择是使包装器消息充当“选项类型”或区别联合。 您可以拥有一个枚举(每个消息类型一个)和一个包含消息类型的字段的消息,然后每个消息类型一个可选字段。
这在Protobuf文档中描述为“联合类型” 。
你可以像这样包装它。 数据将保存实际消息的位置。
message MyCustomProtocol {
required int32 protocolVersion = 1;
required int32 messageType = 2;
bytes data = 3;
}
协议的一般规则是包括协议版本。 一旦有新老客户,您将非常乐意拥有它。
您可以使用一种名为Self Describing Messages的技术。 它可用于生成一组.proto文件,这些文件描述在包装器中编码为“任何”的每种消息类型。 来自文档的一个例子:
syntax = "proto3";
import "google/protobuf/any.proto";
import "google/protobuf/descriptor.proto";
message SelfDescribingMessage {
// Set of FileDescriptorProtos which describe the type and its dependencies.
google.protobuf.FileDescriptorSet descriptor_set = 1;
// The message and its type, encoded as an Any message.
google.protobuf.Any message = 2;
}
应该注意的是,在编写此响应时对这些消息的本机支持仅在C ++和Java中可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.