【问题标题】:What is the difference between using ZMQ PUB with .connect() or .bind() methods?将 ZMQ PUB 与 .connect() 或 .bind() 方法一起使用有什么区别?
【发布时间】:2018-05-09 19:19:09
【问题描述】:

在 Python ZMQ publisher/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')

【问题讨论】:

    标签: python sockets bind zeromq pyzmq


    【解决方案1】:

    这里没有区别(单个发布者和订阅者),但在其他情况下(多个发布者或订阅者),根据您的策略不同:

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

    • Machine2 --> 有一个publisher(带有.connect(Server IP)

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

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

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

    [注意]:

    【讨论】:

      【解决方案2】:

      运营层面的差异,没有。

      设置视角差异 - .bind() 方法不需要知道实际地址(使用通配符扩展技巧等),@987654322 @ 方法必须知道它将开始尝试.connect()-to 的目标地址。

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

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

      【讨论】:

      • 感谢指导,RTO是什么意思?
      • 抱歉,行话,RTO代表Ready-To-Operate(一种状态,当组件/进程/系统确实已准备好启动时)
      • 非常感谢。对于这两种情况的区别,我实现了两种情况,我第一时间把它放在这里。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 2011-08-14
      • 1970-01-01
      相关资源
      最近更新 更多