jeffbass / imagezmq

A set of Python classes that transport OpenCV images from one computer to another using PyZMQ messaging.
MIT License
1.01k stars 160 forks source link

how to set "connetct_to" for computers no in the same local network #43

Closed panecho closed 3 years ago

panecho commented 3 years ago

@jeffbass I get two computers A and B which can be accessed with ssh with public IP x.x.x.x: for A : ssh -p 6000 usernameA@x.x.x.x for B : ssh -p 6001 usernameB@x.x.x.x How should I set the "connect_to" for sender if B as a sender and A as receiver here?

jeffbass commented 3 years ago

TCP and IP addresses and ports can be tricky. I don’t know if you are using REQ/REP or PUB/SUB, so I will describe both here. Yours is a good question, I think I will add some version of this to the imageZMQ documentation.

Instantiation and specifying addresses is quite different for the REQ/REP and PUB/SUB messaging patterns. In REQ/REP, every sending computer connects to the same receiving computer’s address; the receiving computer does not need to know the addresses of the senders. In PUB/SUB, every sending computer specifies the same localhost style address. The receiving computer must instantiate the ImageHub using the address of the first sender; it then uses the ImageHub.connect() method for connecting to any additional sending computers. Here are examples of both messaging patterns with one image receiver and 2 image senders. The TCP addresses are specified the same way whether the sending computers and the receiving computer are in the same network or in different networks. In these examples, the receiver is in one network and the senders are in a different network:

For these examples, let's assume:
Receiving computer ip address:  192.168.1.190

Sending computer 1 ip address: 172.217.14.78 
Sending computer 2 ip address: 172.217.14.39

In the terminology of imageZMQ, an image sender is an instance of the ImageSender class. An image receiver is an instance of the ImageHub class.

The imageZMQ port used for the receiver and for every sender must be the same. The imageZMQ port must not be used by any other process on either computer (whether by ssh or by any other program). Port 5555 is used for imageZMQ in these examples, but any other unused available port could be used.

Here is a REQ/REP example:

# REQ/REP example:
    # on the image sending computer: 
    image_sender = imagezmq.ImageSender(connect_to='tcp://192.168.1.190:5555’) 

    # on the image receiving computer:
    image_hub = imagezmq.ImageHub(open_port='tcp://*:5555’)  # or can be open_port='tcp://127.0.0.1:5555'

    # on 2nd image sending computer, if there is one:
    image_sender = imagezmq.ImageSender(connect_to='tcp://192.168.1.190:5555’)  # it is the same for all sending computers

    # on the receiving computer, nothing needs to be done for additional senders. In REQ/REP there is exactly one ImageHub instantiation even when there are multiple senders.
    # All sending computers specify the same receiver address. The receiving computer will connect additional senders naming them in any additional method.

And here is a PUB/SUB example:

# PUB/SUB example:
    # on sending computer:
    image_sender = imagezmq.ImageSender(connect_to='tcp://*:5555', REQ_REP=False)  # or can be connect_to='tcp://127.0.0.1:5555’

    # on the image receiving computer:
    image_hub = imagezmq.ImageHub(open_port='tcp://172.217.14.78:5555', REQ_REP=False)  # must specify the address for first sending computer

    # on 2nd image sending computer, if there is one:
    image_sender = imagezmq.ImageSender(connect_to='tcp://*:5555', REQ_REP=False)  # it is the same for all sending computers

    # on the image receiving computer, we must connect to the 2nd sending computer's address (this is not needed for REQ/REP)
    second_subscriber = image_hub.connect('tcp://172.217.14.39:5555’)  # there is one required positional argument: the ip address of 2nd sending computer.
    # this line must be repeated to specify the address of every additional sender that this image_hub needs to connect.

In REQ/REP, the sender is the ZMQ Requester (REQ). There is one instantiation of ImageSender and it is the same on all sending computers; it always specifies the same receiver address. The image receiver is the ZMQ Replier (REP). On the receiving computer, the ImageHub is instantiated only once, even if there are multiple senders. It does NOT specify a sender’s address (only its own localhost address). The one and only instantiation of the ImageHub receives images from any senders that connect to it, whether that is one sender or many senders. Also, since REQ_REP=True is the default, we don’t need to specify it.

In PUB/SUB, the sender is the ZMQ Publisher (PUB). There is one instantiation for each ImageSender and it is the same for all sending computers. The image receiving computer is the ZMQ Subscriber (SUB). The image receiver must know and explicitly specify the address of each image sender. Connecting to first sender is the instantiation of the ImageHub and it specifies the address of the first sender. Connecting to additional senders, if any, uses a connect() method for the image_hub that was instantiated for the first sender. There is one and only one instantiation of ImageHub on the receiving computer. But an image_hub.connect() method call is required for each additional sender after the first one. For PUB/SUB, we must specify REQ_REP=False for the instantiation of ImageSender on the sending computer and we must specify REQ_REP=false for the instantiation of ImageHub on the receiving computer. The image_hub.connect() method specifies a tcp address and no other arguments.

Question: do you think that the above is helpful? Should I add this as a page to the imageZMQ documentation?