Chapter 2 - Sockets and Patterns【选译,哈哈】 Part 2 Messags Partterns

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和参考手册中,消息和帧之间存在一些模糊。这里有一个有用的词汇:

一条消息可以是一个或多个部分。

 这些部分也被称为frames。
 每个部分都是一个zmq_msg_t对象。
 在低级API中,您分别发送和接收每个部分。
 更高级的api提供了发送整个多部分消息的包装器。
 
关于信息,还有一些其他值得了解的事情:
你可以发送零长度的消息,例如,从一个线程发送一个信号到另一个线程。
ZeroMQ保证提供消息的所有部分(一个或多个),或者一个都不提供。
ZeroMQ不会立即发送消息(单个或多部分),而是在以后某个不确定的时间发送。因此,多部分消息必须适合于内存。
如果希望发送任意大小的文件,应该将它们分成几部分,并将每一部分作为单独的单部分消息发送。使用多部分数据不会减少内存消耗。
必须在接收到消息后调用zmq_msg_close(),有些语言在scope关闭时不会自动销毁对象。发送消息后不调用此方法。
 
重复一下,不要使用zmq_msg_init_data()。这是一个零复制方法,肯定会给您带来麻烦。在您开始担心如何减少微秒之前,ZeroMQ还有更重要的东西需要了解。
posted @ 2021-09-19 10:00  水色天空  阅读(54)  评论(0编辑  收藏  举报