使用ZMQ PUB与.connect()或.bind()方法有什么区别?

时间:2017-11-26 11:59:16

标签: python bind zeromq connect pyzmq

在Python ZMQ 发布商/订阅者示例模板中,发布商使用 .bind() 方法,订阅者使用.connect()方法连接到绑定IP地址。

但我们可以将.bind().connect()替换为另一个。

我的问题是,下面确定的两个案例有什么区别? (在这些情况下两个脚本工作正常)

第一种情况,默认情况下:

pub1.py:

import zmq
import time
from datetime import datetime

def create_pub_socket():
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://127.0.0.1:9002")  # notice
    return socket

def publish(pub_socket):
    message = {
        'data': 'hi my name is benyamin',
        'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
    }
    pub_socket.send_json(message, 0)
    return message

if __name__ == '__main__':
    socket = create_pub_socket()

    while True:
        print('\n')
        print('publisher: ', publish(socket))
        time.sleep(1)

sub1.py:

import zmq

if __name__ == '__main__':
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, "")
    socket.connect("tcp://127.0.0.1:9002")  # notice

    while True:
        data = socket.recv_json()
        print('subscriber: ', data)
        print('\n')

第二种情况,作为修改后的设置,颠倒了.connect().bind()方法的使用:

pub2.py:

import zmq
import time
from datetime import datetime

def create_pub_socket():
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.connect("tcp://127.0.0.1:9002")  # notice
    return socket

def publish(pub_socket):
    message = {
        'data': 'hi my name is benyamin',
        'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
    }
    pub_socket.send_json(message, 0)
    return message

if __name__ == '__main__':
    socket = create_pub_socket()

    while True:
        print('\n')
        print('publisher: ', publish(socket))
        time.sleep(1)

sub2.py:

import zmq

if __name__ == '__main__':
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, "")
    socket.bind("tcp://127.0.0.1:9002")  # notice

    while True:
        data = socket.recv_json()
        print('second subscriber: ', data)
        print('\n')

2 个答案:

答案 0 :(得分:2)

此处没有差异,但在其他情况下,差异取决于您的政策:

即。假设有两个客户端( Machine1 Machine2 )和服务器
每个客户都必须使用 ZMQ 发布数据,而服务器必须从 Machine1 Machine2 :

  • Machine1 - >有发布者(使用.connect(Server IP)

  • Machine2 - >有发布者(使用.connect(Server IP)

  • 服务器 - >有订阅者(使用.bind(Server IP/Self IP)

正如您在上述场景中所见,我们在第二种情况下使用(在上述问题中)。

[注意]:

答案 1 :(得分:1)

操作级差异,没有。

设置视角差异 - .bind() 方法无需知道实际地址(使用wildcard-expansio tricks等), .connect()方法必须知道一个目标地址,它将开始尝试.connect() - 来。

传输级/可伸缩正式通信模式原型 - 有些情况下,当某些实例化/成为RTO的顺序对于正确的原型服务是强制性的,所以,是的,当存在一个,在任何远程.bind()有机会成功之前,.connect()必须提前成为RTO。

可用于配置.bind()的附加功能 - 是最后一组主要差异,其中一些更新的ZeroMQ API版本3.2+开始添加一些新访问权限 - .bind()侧节点的控制和类似的防御选项,以便在进入公共互联网暴露的操作方式后帮助管理大量风险。