【问题标题】:How to send byte message with ZeroMQ PUB / SUB setting?如何使用 ZeroMQ PUB / SUB 设置发送字节消息?
【发布时间】:2017-01-08 04:19:26
【问题描述】:

所以我是 ZeroMQ 的新手,我正在尝试使用 ZeroMQ 发送字节消息,使用 PUB / SUB 设置。

编程语言的选择对于这个问题并不重要,因为我使用 ZeroMQ 在多种语言之间进行通信。

这是我在 python 中的服务器代码:

import zmq
import time

port = "5556"
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)
while True:
    socket.send(b'\x84\xa5Title\xa2hi\xa1y\xcb\x00\x00\x00\x00\x00\x00\x00\x00\xa1x\xcb@\x1c\x00\x00\x00\x00\x00\x00\xa4Data\x08')
    time.sleep(1)

这是我在 python 中的客户端代码:

import zmq

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")

total_value = 0
for update_nbr in range (5):
    string = socket.recv()
    print (string)

我的客户只是通过 string = socket.recv() 阻止。

我已经做了一些研究,所以显然,如果我要使用PUB / SUB 设置发送字符串,我需要设置一些“主题过滤器”以使其工作。但是如果我要发送一些字节消息,我不确定该怎么做。

【问题讨论】:

  • 我自己解决了这个问题。需要使用 Pub-Sub-Message-Envelopes。 zguide.zeromq.org/page%3aall#Pub-Sub-Message-Envelopes
  • 好吧,虽然使用(人工)消息数据拆分为双帧“信封”是主要问题的一个可能的侧面步骤并且仍然可能,但它有几个非零附加成本 - a) 消息不再是本地 PUB/SUB 消息(一些编程语言绑定碰巧在静默中完成了这一步骤,因此接收 SUB 不需要知道处理到达消息(推广为普通的 PUB/SUB 之一)作为多帧组合和跨平台解决方案造成破坏)+ b)重构。字节正确订阅是零成本的干净解决方案。

标签: zeromq distributed-computing pyzmq low-latency


【解决方案1】:

ZeroMQ 定义了协议,保证行为和消息内容的跨平台兼容性

根本原因:
要开始接收消息
必须更改 SUB 套接字的初始“主题过滤器”状态
(最初是“无接收”-订阅)

ZeroMQ 是一组可爱的工具,围绕智能原则创建。

其中一个说,在 SUB 方面什么都不做,直到 .setsockopt( zmq.SUBSCRIBE, ... ) 明确说明要订阅什么,开始检查传入的消息(老 zmq-fans 记得最初的设计,PUB-side 总是将所有消息分发到每个连接的 SUB-“无线电广播接收器” ,在收到每条消息时,SUB 端会自行执行“主题过滤”。较新版本的 zmq 反转架构并执行 PUB 端过滤)。

无论如何,“主题过滤器”的初始状态是有意义的。谁知道应该先收到什么?没有人。所以什么也得不到。

如果您需要或希望开始这项工作,订阅任何内容的简单步骤......让任何消息都能通过。

是的,就是这么简单.setsockopt( zmq.SUBSCRIBE, "" )

如果需要一些基于键的处理并且消息具有合理的大小(没有 giga-BLOB),则可以简单地在消息字符串前面添加一些键(或者一个字节字段,如果更 hacky 的话)(或有效载荷字节字段)。

当然,如果在 PUB 一侧执行 zmq 过滤(对旧 API 版本无效),可以节省一部分传输层开销,否则在处理消息负载的其余部分之前,订阅接收“任何内容”并检查消息中是否有一些预组装的上下文键(前缀子字符串、字节字段等)通常没什么大不了的。


最好的下一步:

如果您的代码努力进入生产状态,而不是仅仅停留在学术示例中,则必须做更多的工作,才能为恶劣的现实世界生产环境提供生存能力。

这样做的绝佳视角以及使用 ZeroMQ 进行现实设计的好读物是 Pieter HINTJEN 的书“Code Connected, Vol.1” (may check my posts on ZeroMQ to find the book's direct pdf-link) .

ZeroMQ 的共同之父 Martin SUSTRIK 的另一篇精彩文章来自 low-level truths about the ZeroMQ implementation details & scale-ability

【讨论】:

  • Yes, that simple .setsockopt( zmq.SUBSCRIBE, "" ) 实际上,订阅二进制消息,第二个参数必须是b"" 而不是""。我刚刚测试过。
  • @RestInPeace 好吧,这不是 ZeroMQ 属性,这是 Py3 如何开始以不同的方式处理同一件事的副作用,Py2.x 多年来一直这样做......最确定、最稳定的是过去……未来?好吧,谁知道... :o)
  • 哦,我明白了。我只使用过python 3.6-3.8,所以我不能说python 2,但我只是让你知道""实际上使我的程序崩溃了,只有b''b""适用于我当前的python版本是 3.8。不过对于setsockopt_string"" 效果很好。这实际上是有道理的,因为 setsockopt 接收字节,而 setsockopt_string 接收字符串。
猜你喜欢
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 2016-01-28
  • 2022-01-01
  • 1970-01-01
  • 2020-02-21
相关资源
最近更新 更多