zmq - when to use zmq_bind or zmq_connect

q0987 picture q0987 · Apr 19, 2013 · Viewed 8k times · Source
Refer to http://hintjens.wdfiles.com/local--files/main:files/cc1pe.pdf
Page 22 Chapter Divide and Conquer

                    Ventilator[PUSH]
        ___________________|____________________             
        |                  |                   |
[PULL]Worker[PUSH] [PULL]Worker[PUSH]  [PULL]Worker[PUSH]
        |__________________|___________________|             
                           |                   
                     [PULL]Sink

// taskvent.c
    //  Socket to send messages on
    void *context = zmq_ctx_new ();
    void *sender = zmq_socket (context, ZMQ_PUSH);
    zmq_bind (sender, "tcp://*:5557");

    //  Socket to send start of batch message on
    void *sink = zmq_socket (context, ZMQ_PUSH);
    zmq_connect (sink, "tcp://localhost:5558");

// taskwork.c
    //  Socket to receive messages on
    void *context = zmq_ctx_new ();
    void *receiver = zmq_socket (context, ZMQ_PULL);
    zmq_connect (receiver, "tcp://localhost:5557");

    //  Socket to send messages to
    void *sender = zmq_socket (context, ZMQ_PUSH);
    zmq_connect (sender, "tcp://localhost:5558");

// tasksink.c
    //  Prepare our context and socket
    void *context = zmq_ctx_new ();
    void *receiver = zmq_socket (context, ZMQ_PULL);
    zmq_bind (receiver, "tcp://*:5558");

I feel confused when to use zmq_bind or zmq_connect.
It says that most of time "Server" uses zmq_bind and "Client" uses zmq_connect.

Question> When I should use zmq_bind and when I should I use zmq_connect?

http://api.zeromq.org/
zmq_bind - accept incoming connections on a socket  
zmq_connect - create outgoing connection from socket

Answer

minrk picture minrk · Apr 19, 2013

There are a few basic principles for which to bind and which to connect. In general, zeromq doesn't care*, it's just up to you what is more convenient.

For a given pair of sockets that will talk to each other, here are a couple of questions to ask to figure out which should bind and which should connect:

  1. Does one of the processes live longer than the other (i.e. does one start, do something, stop, whereas the other sits and runs a long time)? If so, the longer-lived one should bind.
  2. Do you have multiple instances of one side or the other? If so, the one that is not multiple (or the one which has fewer instances) should bind, because that's fewer URLs to keep track of.

These are mostly about making it easier to manage URLs and connections. In the vent/sink example, there is exactly one ventilator and one sink, but there can be any number of workers (zero-to-many). If the sink and vent both bind, then they don't need to know about workers as they come and go. There are only two URLs to keep track of, whereas if the workers bound, you would have to keep track of a URL for every new worker, and tell the sink and/or vent about the new URL every time a new worker arrived.

*it actually can matter in some edge cases, but not generally.