我想使用 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/