Messaging Patterns
内建的ZeroMQ模式有4种:
Request-reply, 它将一组客户端连接到一组服务。这是一个远程过程调用和任务分发模式。
Pub-sub, 它将一组发布者连接到一组订阅者。这是一种数据分发模式。
Pipeline, 它以扇出/扇入模式连接节点,可以有多个步骤和循环。这是一种并行任务分发和收集模式。
Exclusive pair, 它专门连接两个sockets。这是一种用于在进程中连接两个线程的模式,不要与“普通”套接字对混淆。
Working with Messages
libzmq核心库实际上有两个用于发送和接收消息的api。我们已经看到和使用的zmq_send()和zmq_recv()方法是简单的一行程序。我们将经常使用它们,但是zmq_recv()在处理任意消息大小方面很糟糕:它将消息截断为您提供的任何缓冲区大小。因此,还有一个与zmq_msg_t结构一起工作的API,它有一个更丰富但更困难的API:
初始化消息:zmq_msg_init(), zmq_msg_init_size(), zmq_msg_init_data().
发送和接收消息: zmq_msg_send(), zmq_msg_recv().
释放消息:zmq_msg_close()
访问消息内容: zmq_msg_data(), zmq_msg_size(), zmq_msg_more().
使用消息属性:zmq_msg_get(), zmq_msg_set().
消息处理: zmq_msg_copy(), zmq_msg_move().
ZeroMQ消息是适合于内存的任意大小的blob。您可以使用protocol buffers、msgpack、JSON或应用程序需要表达的任何其他内容来进行自己的序列化。选择可移植的数据表示形式是明智的,但您可以自行决定如何取舍。
在内存中,ZeroMQ消息是zmq_msg_t结构(或者取决于您的语言的类)。
使用ZeroMQ Message的基本规则:
您创建并传递zmq_msg_t对象,而不是数据块。
要读取消息,可以使用zmq_msg_init()创建一个空消息,然后将其传递给zmq_msg_recv()。
要把新数据写入消息,可以使用zmq_msg_init_size()创建消息,同时分配一定大小的数据块。然后使用memcpy填充数据,并将消息传递给zmq_msg_send()。
要释放(而不是销毁)消息,可以调用zmq_msg_close()。这将删除一个引用,最终ZeroMQ将销毁消息。
要访问消息内容,可以使用zmq_msg_data()。要知道消息包含多少数据,请使用zmq_msg_size()。
不要使用zmq_msg_move()、zmq_msg_copy()或zmq_msg_init_data(),除非您阅读了手册页并确切地知道为什么需要它们。
在将消息传递给zmq_msg_send()后,ZeroMQ将清除消息,即将大小设置为零。您不能发送相同的消息两次。并且,您不能在发送后访问消息数据。
如果您使用zmq_send()和zmq_recv()传递字节数组,而不是消息结构,那么这些规则就不适用。
如果您希望多次发送相同的消息,并且它是相当大的,那么创建第二个消息,使用zmq_msg_init()初始化它,然后使用zmq_msg_copy()创建第一个消息的副本。这不是复制数据,而是复制引用。然后,您可以发送消息两次(如果创建更多副本,则可以发送更多),并且只有在发送或关闭最后一个副本时,消息才会最终被销毁。
ZeroMQ还支持多部分消息,它允许您将帧列表作为单个在线消息发送或接收。这在实际应用中得到了广泛的应用。
最初,ZeroMQ消息是一帧,就像UDP一样。我们后来用多部分消息扩展了这个功能,多部分消息是一系列简单的帧,“more”位设为1,后面跟着一个位设为0的帧。ZeroMQ API允许你写带有“more”标志的消息,当你读消息时,它让你检查是否有“more”标志。
在低级的ZeroMQ API和参考手册中,消息和帧之间存在一些模糊。这里有一个有用的词汇:
一条消息可以是一个或多个部分。