PyZMQ ( ZeroMQ ) - 如何从 SUB 套接字获取订阅密钥?

Posted

技术标签:

【中文标题】PyZMQ ( ZeroMQ ) - 如何从 SUB 套接字获取订阅密钥?【英文标题】:PyZMQ ( ZeroMQ ) - How to get a subscription key from a SUB-socket? 【发布时间】:2018-06-28 04:06:23 【问题描述】:

我想在订阅者 (SUB) 套接字设置后获取订阅密钥。

假设我有以下套接字:

import zmq
ctx = zmq.Context.instance()
sub_sock = ctx.socket(zmq.SUB)
sub_sock.bind("tcp://127.0.0.1:6667")
sub_sock.setsockopt(zmq.SUBSCRIBE, "foo1".encode('ascii'))

我想做的是这样的(伪代码):

sub_key = sub_sock.get_sub_key().decode("ascii")
sub_key = subkey[:-1] + "2"  # "foo2"

# unsubscribe all keys
sub_sock.setsockopt(zmq.UNSUBSCRIBE, '')

# subscribe to new key
sub_sock.setsockopt(zmq.SUBSCRIBE, sub_key.encode('ascii'))

问题:

但是,我找不到可以检索订户套接字密钥的函数。如何检索套接字的订阅密钥?

系统:

Python 3.6 libzmq 版本:4.2.5 pyzmq 版本:17.0.0

【问题讨论】:

值得 [+1] 引用所有版本详细信息。 【参考方案1】:

我如何检索套接字的订阅密钥(...设置后)

是的,可以,但只能在 PUB 方面(嗯,实际上是 @987654323 的 XPUB 克隆@-behaviour archetype ) 如果已经使用 .setsockopt( XPUB_VERBOSE | XPUB_VERBOSER , 1 ) 方法仔细配置,以便在此特定模式下开始服务与通道相关的 (X)SUB-s。

因此,在极端需要的情况下(在 SUB 端完全丢失上下文或遭受其自己的订阅管理失忆的情况下),可以将 XSUB 设置为也实例化一个实用的XPUB-instance这个额外的.setsockopt( XPUB_VERBOSE | XPUB_VERBOSER , 1 ) 配置, .bind() | .connect() 一个从 Home-Base 到-Home-Base 的链接,并即时处理所有到达的 (X)SUB-subscription 详细信息。

本机 API 文档发布了正确执行此操作的所有详细信息。

一种通过窃听来了解自己的订阅详细信息的独特方法,但可行。


最后的评论:

ZeroMQ 主题过滤器以更复杂的方式设计,并针对速度进行了优化(高吞吐量,低延迟)。它可以为每个 .bind() | .connected() 对等点处理单位、数百、数千、数万个订阅。

这些设计愿望和对性能的关注是原因,没有这样的功能可以事后要求“图书馆员”找到所有“我自己的”订阅密钥(无论是从不记得还是完全忘记)。

人们也可能意识到,从 API v4.x 开始,ZeroMQ 原生处理开始在 (X)PUB 端管理主题过滤,而旧 API 版本报告此性能关键操作被推迟到每个(X)SUB-side(s),以增加原始网络流量的累积量为代价,因为所有消息(是的,确实是所有消息)都从(X)PUB 到所有(X)SUB-s。有人在这里提到安全问题吗?

# unsubscribe all keys                        // THIS WILL NOT FLY THAT WAY

同样的理由支持“丢失”的 API 调用,要求“忘记我自己的所有订阅”,但必须以一种一种方式或正确地明确取消订阅 @987654336 @(X)SUB-side socket-instance,而是在绿地的基础上重新实例化另一个,并将其重新 .bind() | .connect() 返回到基础设施,以实现整体目标。

【讨论】:

【参考方案2】:

不支持从 SUB 套接字获取订阅。您需要将它们存储在您自己的数据结构中(列表、地图等)

其他一些信息:

SUB 套接字支持多个同时订阅。

下面的行并没有取消订阅所有键,它实际上取消了键""这是一个有效的订阅。

# unsubscribe all keys
sub_sock.setsockopt(zmq.UNSUBSCRIBE, '')

你需要明确:

sub_sock.setsockopt(zmq.UNSUBSCRIBE, "foo1".encode('ascii'))

【讨论】:

感谢您提到'' 并不代表所有键。

以上是关于PyZMQ ( ZeroMQ ) - 如何从 SUB 套接字获取订阅密钥?的主要内容,如果未能解决你的问题,请参考以下文章

Zeromq 内存泄漏 (pyzmq)

ZeroMQ-PyZmq Tornado Event Loop

termux之jupyter安装libzmq安装失败

带有 Qt 5.12 QSocketNotifier 的 ZeroMQ 只触发一次

SaltStack

浅谈saltstack