zeromq怎样获取已经绑定的socket节点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zeromq怎样获取已经绑定的socket节点相关的知识,希望对你有一定的参考价值。

您好,ZeroMQ是一个开源的消息传递库,它可以帮助开发者轻松地创建分布式应用程序。ZeroMQ可以使用TCP/IP协议绑定到一个或多个socket节点,以便在多个节点之间传输消息。ZeroMQ的主要优势在于它具有高性能,可以在多个节点之间快速传输数据。ZeroMQ的另一个优势是它可以轻松地实现多种消息传输模式,例如发布/订阅,请求/响应,管道等。

要获取已经绑定的socket节点,可以使用ZeroMQ的zmq_socket函数。此函数接受一个参数,该参数指定要绑定的socket节点的类型。例如,可以使用zmq_socket函数来绑定TCP/IP socket节点,也可以使用zmq_socket函数来绑定UDP socket节点。

此外,ZeroMQ还提供了zmq_bind函数,该函数可以用于绑定socket节点到指定的端口。此外,ZeroMQ还提供了zmq_connect函数,该函数可以用于连接到远程socket节点。

总之,ZeroMQ可以轻松地绑定到一个或多个socket节点,以便在多个节点之间传输消息。ZeroMQ提供了zmq_socket函数和zmq_bind函数,可以用于绑定socket节点,以及zmq_connect函数,可以用于连接到远程socket节点。
参考技术A zmq_bind() 函数绑定把一个socket绑定在一个本地的网络节点(endpoint)上,然后开始接收连接到本节点上的其它节点发送来的消息。

节点是一个字符串,它包括一个协议://然后跟着一个address。协议为下列给定的协议中的一个。address指定了进行绑定的地址。

ØMQ支持以下几种传输协议:

tcp
点对点传输协议tcp,参见zmq_tcp(7)

ipc
本地线程间通信,参见zmq_ipc(7)

inproc
本地进程内(线程间)通信,参见zmq_inproc(7)

pgm,epgm
使用PGM进行可靠的多路广播,参见zmq_pgm(7)

除了ZMQ_PAIR之外,所有的ZMQ socket类型都支持一对多和多对一传输方式。这种精确的多路传输依赖于在zmq_socket(3)中定义的socket类型。

ipc和tcp传输方式接受通配符形式的地址:更多细节参见zmq_ipc(7)和zmq_tcp(7)。

对于zmq_bind()和zmq_connect()来说,tcp,pgm和epgm的地址语法形式可能比较特别。
紧跟着zmq_bind()函数之后的操作,是这个socket开启一种静音状态,直到至少一条到来的或发出去的连接被创建,而那个连接的发起者处在预备状态。在静音状态的时候,socket会根据在zmq_socket(3)中定义的类型而选择阻塞或者丢弃消息。相对的,libzmq:zmq_connect[3]函数之后,socket会处于预备状态。

Return value
如果zmq_bind()执行成功会返回0。其它情况则返回-1并且设置errno为下列的对应的值。
参考技术B 你可以使用zeromq的zmq_getsockopt API函数来获取绑定的socket节点信息,这个API函数允许你获取zeromq服务端socket绑定的本地地址和端口号。 参考技术C 首先弄明白0MQ中的“socket”和传统意义上socket的一些差异。 我认为ZeroMQ不能算作单纯的socket库,它应该算是一个messaging library,一个“轻量级”的消息队列库(这里所说的“轻量级”是与过去一些企业级的消息队列对比而言的)。正如我前面列出的两个大神所说的:socket只是表现形式,而通信模式才是其本质。 也就是说,在学0MQ的时候,不要把0MQ中的socket和系统本身的socket弄混。我们可以看看zmq_socket的文档: zmq_socket(3) (zguide告诉我们,这份文档要时不时的拿出来要多读几遍) 注意,每一种不同类型的“socket”,都有自己的消息模式。这其中包括该类型套接字可以和哪些套接字连接到一起工作啊(Compatible peer sockets)、消息传递的方向啊(Direction)、消息收发模式啊(Send/receive pattern)、还有Outgoing routing和Incoming routing用到的一些调度算法啊(比如:Round-robin、Fair-queued,这些调度算法在操作系统课程中应该会有涉及)。当我们创建一个0MQ套接字后,我们实际上得到的是一个加了各种特效的“socket”。 上面一段话,我意在说明,0MQ中的“socket”没那么简单。借用@Dirk Chang答案中“模式”一词,0MQ实际上是把一些在实践中总结出来的消息通信模型封装成不同类型的套接字,以供我们使用。

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

【中文标题】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'))

【讨论】:

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

以上是关于zeromq怎样获取已经绑定的socket节点的主要内容,如果未能解决你的问题,请参考以下文章

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

如何识别没有订阅者的节点? (零MQ)

ZeroMQ:如何获取连接客户端的地址?

如何使用 socket.io 获取用户的 IP 地址?

java:ServerSocket中获取所有连接上的Socket

ZeroMQ_10 节点协调