message-queue - 如何知道字节数组是哪个protobuf消息?

标签 message-queue protocol-buffers

我想使用 protobuf 而不是 Json 在消息队列之间进行通信。

当只有一个 proto 消息时,我知道如何处理它。

假设 proto 文件是:

//person.proto
syntax = "proto3";

option java_outer_classname = "PersonProto";

message Person {
    int32 id = 2;
    string name = 1;
    string email = 3;
}

现在,我可以用下面的方法来处理它:
PersonProto.Person person = PersonProto.Person.newBuilder()
        .setEmail("123@test.com")
        .setId(1)
        .setName("name-test")
        .build();

byte[] bytes = person.toByteArray();

//Transfer from publisher to consumer between message queue.

//I can deserialise it, because i know the proto message is Person.
PersonProto.Person.parseFrom(bytes);

但是如果有多个 proto 消息怎么办?

假设还有另一个名为 Address 的原始消息.
syntax = "proto3";

option java_outer_classname = "PersonProto";

message Person {
    int32 id = 2;
    string name = 1;
    string email = 3;
}

message Address {
    string address = 1;
}

当消费者从消息队列收到字节数组时,如何知道它是哪个原始消息?以及如何反序列化字节数组?

最佳答案

Protobuf 3 引入了 Any 的概念这可以以类似于@AdamCozzette 解释的顶级消息模式的方式起作用。

在写入端,您将消息打包在 Any 中:

Person person = ...
Any any = Any.pack(person);

out.write(any.toByteArray());

然后在读取端,您读入 Any并打开您感兴趣的类型:
Any any = Any.parseFrom(in);

if (any.is(Person.class)
{
  Person person = any.unpack(Person.class);
  ...
}
else if (any.is(Address.class);
{
  Address address = any.unpack(Address.class);
  ...
}
else
{
  //Handle unknown message
}

使用 Any消除了对特殊消息类型(顶级消息)的需要,但也消除了类型安全元素,因为您可能会收到消费代码不知道如何处理的消息。

关于message-queue - 如何知道字节数组是哪个protobuf消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40450556/

相关文章:

RabbitMQ — 为什么错误的订阅者会收到已发布的消息?

c# - 在窗口出现之前拦截并隐藏它

java - Akka grpc 可以消费非 Akka 服务的数据吗

google-app-engine - 带和不带 Protocol Buffers 的 Google Cloud Datastore

multithreading - 消息队列消息之间的依赖

rest - ServiceStack Web 服务的存储转发故障转移解决方案

go - 在 golang 中导入 “google/protobuf/descriptor.proto”

c - nanopb( Protocol Buffer 库)重复子消息编码

python - 存储为 Oracle BLOB : python retrieve fails 的 Protocol Buffer

c++ - WM_QUIT 只发布线程而不是窗口?