简体   繁体   English

ZeroMQ发布订户

[英]ZeroMQ publishing subscriber

Is it possible to have a publisher and subscriber in one thread? 是否可以在一个线程中拥有发布者和订阅者? Whenever I do 每当我做

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")

The subscription does not work (ie message don't arrive). 订阅无效(即消息未到达)。 When I used socket_recv.bind() the sending does not work (using bind() on socket_send and socket_recv causes an address-already-used error). 当我使用socket_recv.bind() ,发送不起作用bind()socket_sendsocket_recv上使用bind()会导致地址已使用的错误)。

Any idea of how I can resolve this? 关于如何解决这个问题的任何想法吗? I have a multiple clients writing messages to the pub-sub message bus, then I used the ventilator example to distribute the messages to workers and these workers write back to the ventilator which sends the results back to the clients (worker - ventilator communication is a different communication). 我有多个客户端将消息写入pub-sub消息总线,然后我使用呼吸机示例将消息分发给工作人员,然后这些工作人员写回呼吸机,然后将结果发送回客户端(工作人员-呼吸机通信是不同的沟通)。 Perhaps there's a better communication pattern to handle this... 也许有更好的沟通方式可以解决这个问题...

You almost always want to run a ready-to-go example of the pattern you want to use first just to confirm everything seems to be in working order. 您几乎总是想运行一个您想首先使用的模式的现成示例,只是为了确认一切似乎都正常。 Unfortunately I don't see any ready made examples in pyzmq (which is, I assume, the binding you're using) with pub/sub both in the same thread, but I have seen and run such examples in other languages so it's not a limitation of ZMQ and should be possible in your situation. 不幸的是,我在pyzmq(我假设您正在使用的绑定)中都没有在同一线程中使用pub / sub看到任何现成的示例,但是我已经看到并以其他语言运行了这样的示例,所以没有ZMQ的限制,在您的情况下应该是可能的。

There are a couple of things you'll want to look at. 您需要看几件事。 Your code sample is very sparse, there's no way for anyone to diagnose what's going on from that, but here's some suggestions: 您的代码示例非常稀疏,任何人都无法诊断由此产生的后果,但是这里有一些建议:

  • Before trying to subscribe to a specific topic (in your case, "id1"), try subscribing to everything : socket_recv.setsockopt(zmq.SUBSCRIBE, "") - this will remove the possibility that you're not setting up the subscription properly. 在尝试订阅特定主题(在您的情况下为“ id1”)之前,请尝试订阅所有内容socket_recv.setsockopt(zmq.SUBSCRIBE, "") -这将消除您未正确设置订阅的可能性。
  • Along the same lines, when you do subscribe to "id1", make sure your message is either a single frame message that begins with the string "id1", or it's a multi-frame message with "id1" as the first frame. 同样,当您确实订阅“ id1”时,请确保您的消息是以字符串“ id1”开头的单帧消息,还是以“ id1”作为第一帧的多帧消息。
  • I assume all of this is being run in a synchronous context, which means your subscriber should finish connecting before you move on to the next line, but just make sure that's true... if you should start publishing your message before your subscriber is finished connecting, that message will be lost. 我假设所有这些都在同步上下文中运行,这意味着您的订户应该在继续进行下一行之前完成连接,但是请确保这是正确的...如果您应该在订户完成之前开始发布消息连接,该消息将丢失。

As you note, you can't bind() twice on the same address, something useful to keep in mind. 正如您所注意到的,您不能在同一地址上两次bind() ,请记住这一点。 You want to think of one side of the socket pair as a "server" (which really means the constant element) and the other side as a "client" (which really means the unreliable element)... if they both are just as constant and both as reliable, pick the one that "owns" or "originates" the data (in pub/sub, this would always be the publisher) and mark that one the "server"... you want to bind() on your server, and connect() on your client. 您想将套接字对的一侧视为“服务器”(这实际上意味着常量元素),而将另一侧视为“客户端”(这实际上意味着不稳定的元素)……如果它们两者都一样恒定且可靠。选择一个“拥有”或“创建”数据的对象(在pub / sub中,它始终是发布者),然后将其中一个标记为“服务器” ...您要在其上bind()您的服务器,以及客户端上的connect()

All that said... as sberry noted, your proposed use case is bi-directional communication, which doesn't seem to fit pub/sub. 所有这些……正如sberry所指出的那样,您建议的用例是双向通信,似乎不适合pub / sub。 There are many examples of doing what you want to do in the guide , specifically look at reliable request/reply patterns . 这样做有你想在做什么的例子很多指导 ,具体看可靠的请求/应答模式 Your use case is similar enough that you'll probably want to use one of those as a base, and there is python code linked throughout the descriptions of those patterns that will help you understand which code is doing what. 您的用例非常相似,以至于您可能希望使用其中之一作为基础,并且在这些模式的描述中都链接了python代码,这将有助于您了解哪个代码在做什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM