What is the difference between using ZMQ PUB with

2019-02-14 09:04发布

In Python ZMQ publisher/subscriber sample template, the publisher uses .bind() method and the subscriber uses .connect() method, that connected to the bind IP address.

But we can replace .bind() and .connect() each with the other.

My question is that what is the difference between two cases that determined below?
(two scripts in these cases work fine)

The first case, as default:

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')

And the second case, as the modified setup, that reversed the use of the .connect() and .bind() methods:

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条回答
对你真心纯属浪费
2楼-- · 2019-02-14 09:14

No differences at here but in other scenarios, there is difference depend on your policy:

i.e. suppose there are two clients (Machine1, Machine2) and a Server.
Each client must publish data using ZMQ, and the Server must subscribe that data from Machine1 and Machine2:

  • Machine1 --> has a publisher (with .connect(Server IP) )

  • Machine2 --> has a publisher (with .connect(Server IP) )

  • Server --> has a subscriber (with .bind(Server IP/Self IP))

As you can see in the mentioned scenario we use in the second case (in the mentioned question).


[NOTE]:

  • .bind() method only accepted with self IP or 127.0.0.1, but .connect() method can connected to each IP address that defined in .bind() method: Why doesn't zeromq work on localhost?

  • Here is another example of changing .bind() and .connect() locate: This -Link

查看更多
看我几分像从前
3楼-- · 2019-02-14 09:26

Operational-level difference, there is none.

Setup perspective difference - .bind() method need not know the actual addresses ( using wildcard-expansio tricks et al ), .connect() method has to know a target address to which it will start trying to .connect()-to.

Transport-class / Scalable Formal Communication Pattern Archetype - there are cases, when some order of instantiation / becoming RTO is mandatory for proper archetype service, so, yes, there are differences, when one, .bind() has to become RTO earlier, before any remote .connect() may have a chance to succeed.

Add-on specific features available for configuring the .bind() side - are the last principal set of differences, where some more recent ZeroMQ API versions 3.2+ started to add some new access-control and similar defensive options for the .bind()-side node, so as to help manage plethora of risks once going into public internet exposed modus operandi.

查看更多
登录 后发表回答