绑定,发布,解除绑定,重复

时间:2014-06-20 08:35:34

标签: python messaging zeromq pyzmq

peer.py

import zmq
import time


if __name__ == '__main__':
    context = zmq.Context()

    socket = context.socket(zmq.PUB)

    while True:
        print "I: Publishing"

        socket.bind("tcp://*:5555")
        socket.send_multipart(['general', 'Unique peer information'])
        socket.unbind("tcp://*:5555")

        time.sleep(1)

scanner.py

import zmq


if __name__ == '__main__':
    context = zmq.Context()

    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, 'general')
    socket.connect("tcp://localhost:5555")

    print "I: Scanning 5555"

    while True:
        message = socket.recv_multipart()
        print "I: Receiving: {}".format(message)

我试图在同一个端口上,在同一台计算机上广播多个对等体,并且只有一个扫描仪"听着"看"谁有空。每个对等方将广播其联系信息,然后客户端将使用扫描仪找出可用的信息,然后使用广播的信息通过REQ / REP信道进行连接。

为了完成这项工作,我尝试快速绑定PUB套接字,广播有关对等体的信息,然后取消绑定,以便让其他对等体在不同的时间绑定到同一个套接字,并广播下一个同行的不同标识符集。

我怀疑邮件在被发送之前因为解除绑定而被丢弃(调用close()时也是如此)但是我无法弄清楚如何让邮件清空在关闭连接之前排队,以便不丢弃任何消息。

有什么想法吗?

  • Windows 8.1 x64
  • Python 2.7.7 x64
  • PyZMQ 4.0.4

修改

我在ZMQ邮件列表上问了同样的问题并得到了一些有趣的回复,请看这里:http://lists.zeromq.org/pipermail/zeromq-dev/2014-June/026444.html

2 个答案:

答案 0 :(得分:1)

订阅者必须连接到发布者才能接收任何消息。操作顺序必须如下:

  1. 启动发布者("开始"表示定义套接字并绑定或连接它,对于订阅者,订阅您想要的消息。
  2. 启动订阅者(1和2可以按任何顺序发生)
  3. 发送/接收消息
  4. 旋转一切
  5. PUB套接字是非阻塞的,它们不会等到要发送的订户,它只是将其移动到队列中,如果订户不是&#等待它,它会丢弃它。 Check out the pyzmq pub/sub examples,您会看到订阅者必须在发布者发送消息并知道它已被接收之前宣布自己。

    如果您知道您的订阅者将始终在指定的时间段内可用,您可以使用超时假冒它,否则,发布/订阅不会为您工作。

    所以,正在发生的事情是你的PUB套接字绑定了,但是你的订阅者连接需要非零的时间,即使你先把它旋转起来,所以&#39 ;当你发送信息时,你没准备好。消息被丢弃,然后你将所有内容都缩小,仍然可能在订阅者有机会完全连接之前。

    您需要使用不同类型的套接字对,可能是rep/req,但您正在查找阻塞行为,该行为会在接收器准备好接收消息之前保留消息。这可能意味着使用中央服务器来控制有关哪些对等方可用的信息,而不是尝试将信息广播到所有对等方,或者根据您的消息传递需求和架构将其他内容广播。或者,您需要一个寿命更长的酒吧/子系统。

答案 1 :(得分:1)

根据对ZMQ邮件列表的反馈,这里是我要去的建议,直到更合适的东西出现。剩下的问题是我如何只能在任何时间点运行1台扫描仪。理想情况下,扫描仪将独立于同行和彼此。

思想?

<强> peer.py

import zmq
import time
import uuid

unique_id = uuid.uuid4().get_urn()

if __name__ == '__main__':

    while True:
        print "I: Publishing {}".format(unique_id)

        context = zmq.Context()
        socket = context.socket(zmq.PUSH)
        socket.connect("tcp://127.0.0.1:5555")
        socket.send_multipart(['general', unique_id])
        socket.close()
        context.destroy()

        # Wait for a random amount of time
        time.sleep(1)

<强> scanner.py

import zmq

if __name__ == '__main__'
:
    context = zmq.Context()

    socket = context.socket(zmq.PULL)
    socket.bind("tcp://*:5555")


print "I: Scanning 5555"

    while True:
        message = socket.recv_multipart()
        print "I: Receiving: {}".format(message)