【问题标题】:ZeroMQ publishing subscriberZeroMQ 发布订阅者
【发布时间】:2014-12-24 01:37:57
【问题描述】:

是否可以在一个线程中同时拥有发布者和订阅者?每当我这样做时

socket_send = context.socket(zmq.PUB)
socket_send.bind("tcp://127.0.0.1:5559")

socket_recv = context.socket(zmq.SUB)
socket_recv.connect("tcp://127.0.0.1:5559")
socket_recv.setsockopt(zmq.SUBSCRIBE, "id1")

订阅不起作用(即消息未到达)。当我使用socket_recv.bind() 时,发送不起作用(在socket_sendsocket_recv 上使用bind() 会导致地址已使用错误)。

知道如何解决这个问题吗?我有多个客户端将消息写入 pub-sub 消息总线,然后我使用通风机示例将消息分发给工作人员,这些工作人员写回通风机,通风机将结果发送回客户端(工作人员 - 通风机通信是不同的通讯方式)。也许有更好的沟通模式来处理这个......

【问题讨论】:

  • 您几乎可以肯定并不想这样做。你能澄清几件事吗?您有一个订阅者在监听客户发布他们的主题吗?接收消息并分发给工作人员,然后您想通过发布将结果发送回客户端?客户之所以选择这个,是因为他们也订阅了结果?
  • 据我所知,您很可能需要客户端连接并发送到的路由器。然后,使用轮询器,您从路由器读取并写入经销商。您的每个工作人员都有一个对该 Dealer sock 的引用,阅读他们的工作,完成工作,在 Dealer 上回写,然后在您的主线程(在轮询器中)中,您从 Dealer 读取并在路由器上回写。请注意,Router 和 Dealers 将有多帧消息(您的目标数据将在最后一帧中),因为它使用第一帧作为路由信息。
  • 我认为您的描述符合我的用例。然而,看着this example,我很难弄清楚他们描述的通信的哪一部分(客户到呼吸机或呼吸机到工人?)。此外,工人被识别的事实有点奇怪。
  • 是的,您可以在同一个线程上发送和接收消息,但是当普通的 python 变量可以完成这项工作时,您为什么要这样做呢?我不能说为什么你没有收到消息,因为你没有发布足够的代码。不过,您的设计几乎肯定是错误的;如果您可以用纯粹的功能术语来说明您正在尝试做的事情,而不是用可能不合适的模式来说明它,那么我们会帮助您。
  • @JohnJefferies 你似乎误会了什么。显然,我并不想在一个线程中发送数据。我在问同一个线程是否可以在同一个 pub-sub 消息总线上发送和接收 - 这不一样。

标签: python zeromq distributed-computing


【解决方案1】:

您几乎总是想运行一个您想首先使用的模式的现成示例,以确认一切似乎都处于工作状态。不幸的是,我在 pyzmq 中没有看到任何现成的示例(我假设,您正在使用的绑定)与 pub/sub 都在同一个线程中,但我已经看到并在其他语言中运行了这样的示例,所以它不是ZMQ 的限制,在您的情况下应该是可能的。

您需要查看几件事。您的代码示例非常稀疏,任何人都无法从中诊断出发生了什么,但这里有一些建议:

  • 在尝试订阅特定主题(在您的情况下为“id1”)之前,请尝试订阅所有内容socket_recv.setsockopt(zmq.SUBSCRIBE, "") - 这将消除您未设置正确订阅。
  • 同样,当您进行订阅“id1”时,请确保您的消息是以字符串“id1”开头的单帧消息,或者是多帧消息以“id1”作为第一帧。
  • 我假设所有这些都是在同步上下文中运行的,这意味着您的订阅者应该在您转到下一行之前完成连接,但请确保这是真的...如果您应该在您开始发布您的消息之前订阅者已完成连接,该消息将丢失。

正如您所指出的,您不能在同一个地址上两次bind(),记住这一点很有用。您想将套接字对的一侧视为“服务器”(实际上是指常量元素),将另一侧视为“客户端”(实际上是指不可靠的元素)......如果它们都一样恒定且两者都可靠,选择“拥有”或“发起”数据的那个(在 pub/sub 中,这将始终是发布者)并将那个标记为“服务器”......你想要bind() on你的服务器,connect() 在你的客户端。

所有这一切......正如 sberry 所指出的,您提出的用例是双向通信,这似乎不适合发布/订阅。在the guide中有很多做你想做的事的例子,具体看reliable request/reply patterns。您的用例非常相似,您可能希望使用其中一个作为基础,并且在这些模式的描述中链接了 python 代码,这将帮助您了解哪些代码在做什么。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多