31

ZeroMQ 常见问题页面建议使用 Google 的protobuf作为序列化消息内容的一种方式。

有没有人看到一个很好的用法示例?

我还需要回答“序列化消息的最大优势是什么?” - 它是否可能是我可以没有的东西并利用更细的管道。

.proto我非常喜欢文件和protoc编译器的想法。

此外,似乎另一个在操场上扔的好工具是libev,欢迎任何评论:)

4

4 回答 4

25

如果您 100% 确定将通过 ZMQ 进行通信的程序将始终能够理解彼此的二进制格式(例如,因为它们总是分布在一起并且无论如何都使用相同的编译器选项编译)我认为没有受益于序列化增加的开销。

一旦不能满足上述条件(例如在不同主机类型上运行的合作伙伴程序,用不同语言编写的程序,甚至可以及时独立发展的合作伙伴程序 - 这可能导致其原始二进制结构不兼容),序列化就很可能成为必须。

似乎现在每个人和他们的兄弟都在创建序列化解决方案,这可能表明没有一刀切的解决方案。 此页面包含 27 个(!!)不同序列化系统的序列化时间、反序列化时间和大小的相当彻底的基准测试。不要跳过该页面的第一段,上面写着“警告,基准测试可能会产生误导”。您的应用程序和数据对您来说很重要,但那里提供的数据可能会帮助您缩小要详细研究的选择范围。

于 2011-09-12T16:14:31.233 回答
21

这是一个通过 java 和 C++ 发送和接收消息的示例:

在java中序列化:

Person person = Person.newBuilder().setName("chand")
    .setEmail("chand@test.com").setId(55555).build();
socket.send(person.toByteArray(), 0);

在java中反序列化:

byte[] reply = socket.recv(0);
Person person2 = Person.parseFrom(reply);

在 C++ 中序列化:

Person p = Person();
std::string str;
p.SerializeToString(&str);
int sz = str.length();
zmq::message_t *query = new message_t(sz);
memcpy(query->data (), str.c_str(), sz);
socket->send (*query);

C++中的反序列化

zmq::message_t resultset(100);
socket->recv (&resultset);

Person p = Person();
p.ParseFromArray(resultset.data(), resultset.size());
printf("\n Server : %s", p.name().c_str());
于 2013-02-19T10:03:21.060 回答
3

我不确定 0mq 中的 PUB/SUB 是否可以与 protobuf 一起使用,因为 0mq 期望在 msg 的开头有一个字符串主题。但是 protobuf 首先放置一个字段描述符。

实际上这里是一个解决方案的链接。

http://www.dotkam.com/2011/09/09/zeromq-and-google-protocol-buffers/

干杯

于 2012-10-01T23:55:38.143 回答
2

通信时总是需要序列化。结构是随机访问的。像 ZeroMQ 这样的通信层是串行的。

您可以使用您的语言附带的“默认序列化”。

例如,在 C++ 中,没有指针的结构将具有一定的二进制布局,可以直接转换为字节数组。这种二进制布局间接地是您的序列化层,并且是特定于语言和编译器的。

只要您将自己限制为没有指针的结构,并且在管道的两端使用相同的编译器和语言……请随意避免使用在提供的默认布局之上进行额外序列化的库。

于 2018-02-09T13:29:47.213 回答