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

What is the difference between using ZMQ PUB with .connect() or .bind() methods?

在PythonZMQpublisher/subscriber示例模板中,发布者使用.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')

操作级差,有none.

设置视角差异-.bind()方法不用知道实际地址(使用 wildcard-expansio 技巧等),.connect() 方法 必须知道 它将开始尝试 .connect()-to 的目标地址。

Transport-class/可扩展的正式通信模式原型 - 在某些情况下,某些实例化/成为 RTO 的顺序对于适当的原型服务是强制性的,因此,是的,存在差异,其中之一,.bind() 必须更早成为 RTO,在任何远程 .connect() 可能有机会成功之前。

可用于配置 .bind() 端的附加组件特定功能 - 是最后一组主要差异,其中一些较新的 ZeroMQ API 版本3.2+ 开始为 .bind() 端节点添加一些新的访问控制和类似的防御选项,以便在进入 public 互联网暴露的作案手法时帮助管理过多的风险。

这里没有区别(单个发布者和订阅者),但在其他场景(多个发布者或订阅者)中,根据您的策略有区别:

  1. 即假设有两个客户端 (Machine1, Machine2) 和一个 Server.
    每个客户端必须使用 ZMQ 发布数据,并且 Server 必须从 Machine1[=69= 订阅该数据] 和 Machine2:
  • Machine1 --> 有一个 publisher(有 .connect(Server IP)

  • Machine2 --> 有一个 发布者(有 .connect(Server IP)

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

如您所见,在上述场景中我们使用了问题中的第二种情况。

  1. 然而,如果我们有两个订阅者和一个发布者,我们必须将 .bind() 方法放在发布者中,并将 .connect() 方法放在订阅者中(问题中的第一种情况)。

[注意]:

  • .bind()方法不支持localhost作为IP,而.connect()方法可以连接到每个IP地址在 .bind() 方法中定义:Why doesn't zeromq work on localhost?

  • 这里是另一个改变.bind().connect()的例子定位:This-Link