ZeroMQ同步的PUB-SUB:用户挂起同步,但否则正常工作

时间:2018-11-02 11:30:32

标签: python zeromq pyzmq

我正在使用ZeroMQ建立发布者/订阅者的通信模型。
发布者创建zmq上下文,然后使用PUB打开套接字
沟通模式。然后使用TCP传输协议将其绑定到端口。为了进行同步,将打开一个单独的套接字,该套接字具有在不同路径中绑定的REP通信模式。除非收到msg = syncservice.recv()中的同步请求,否则程序无法继续。然后,它执行一些基本工作,然后重新开始。这是发布者的代码:

import pickle, zmq, random, string

# Wait for 1 subscriber
SUBSCRIBERS_EXPECTED = 1

def randomword(length):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(length))

while True:
    try:
        arguments = {}
        data = {}
        context = zmq.Context()

        # Socket to talk to clients
        publisher = context.socket(zmq.PUB)
        # set SNDHWM, in case of slow subscribers
        publisher.sndhwm = 1100000
        publisher.bind('tcp://*:5561')

        # Socket to receive signals
        syncservice = context.socket(zmq.REP)
        syncservice.bind('tcp://*:5562')

        # Get synchronization from subscribers
        subscribers = 0
        while subscribers < SUBSCRIBERS_EXPECTED:
            # wait for synchronization request
            msg = syncservice.recv()
            # send synchronization reply
            syncservice.send(b'')
            subscribers += 1

        for n in range(1000):
            for i in range(random.randrange(1, 6)):
                arguments[i] = randomword(random.randrange(2, 10))

            data['func_name_' + str(n)] = randomword(8)
            data['arguments_' + str(n)] = arguments

        data_string = pickle.dumps(data)
        publisher.send(data_string)

    except KeyboardInterrupt:
        print("Interrupt received, stopping...")
        break

订阅者的功能几乎与发布者的功能相同,尽管 从订户的角度来看。这是订户的代码:

import pickle, zmq, pprint, time

context = zmq.Context()

# Connect the subscriber socket
subscriber = context.socket(zmq.SUB)
subscriber.connect('tcp://localhost:5561')
subscriber.setsockopt(zmq.SUBSCRIBE, b'')

time.sleep(1)

# Synchronize with publisher
syncclient = context.socket(zmq.REQ)
syncclient.connect('tcp://localhost:5562')

# Initialize poll set
poller = zmq.Poller()
poller.register(syncclient, zmq.POLLIN)
poller.register(subscriber, zmq.POLLIN)

# send a synchronization request
syncclient.send(b'')

while True:
    try:
        socks = dict(poller.poll())

    except KeyboardInterrupt:
        print("Interrupt received, stopping...")
        break

    # wait for synchronization reply
    if syncclient in socks:
        syncclient.recv()
        print('Sync')

    if subscriber in socks:
        msg = subscriber.recv()
        data = pickle.loads(msg)
        pprint.pprint(data)
        syncclient.send(b'')

期望的结果是发布者可以无休止地发布,而 订户不断接收并打印所有内容。如果我删除 同步部分,一切按预期运行。如果我保持同步 多次传输后,用户挂断了一部分。有趣的事情 就是如果我发送键盘中断(Ctrl-C)然后重启订户, 它会再次收到几个传输信号并再次挂起,依此类推

我尝试了不同的高水印设置,但没有任何区别。我尝试过在每次循环后关闭套接字并终止上下文。我已经测试了打印或酸洗(序列化)的开销是否过多,但这也不是。我还修改了suicidal snail example使其在这种情况下可以工作,但订阅者并未死亡。我想念什么? (每个示例都使用Python 3)

0 个答案:

没有答案