0

I'm reading the ZeroMQ Guide and came across the following passage in regards to the ROUTER socket and identities:

An application that uses a ROUTER socket to talk to specific peers can convert a logical address to an identity if it has built the necessary hash table. Because ROUTER sockets only announce the identity of a connection (to a specific peer) when that peer sends a message, you can only really reply to a message, not spontaneously talk to a peer.

This is true even if you flip the rules and make the ROUTER connect to the peer rather than wait for the peer to connect to the ROUTER. However you can force the ROUTER socket to use a logical address in place of its identity. The zmq_setsockopt reference page calls this setting the socket identity.

According to this passage, "you can only really reply to a message, not spontaneously talk to a peer", meaning a ROUTER can't send a message to a specific DEALER, but the next sentence implied that you can if you force the router socket to use a logical address: "However you can force the ROUTER socket to use a logical address in place of its identity". This part confuses me because they just said that you cant spontaneously send messages from a router to a dealer, but now they claim you can. If you follow this link to the guide, you'll see that after this passage, they say "It works as follows", but the steps they give don't seem to clear up how to send a spontaneous message from a ROUTER to a specific DEALER and return a response back to the original ROUTER.

My question: Is it possible for a single ROUTER socket to send a request to a specific DEALER (Out of many) socket and the DEALER send the result of the request back to the ROUTER? And if it is possible, how can this be done?

Follow up question: If this is not possible, is there a better combination of sockets to approach this?

Below is a crude diagram of my intended design:

enter image description here

Basically, the client send a request to 1 specific server, that server processes the request and returns the result of the request to the client. The client now has that result, and it knows what server it was processed on.

user3666197
  • 1
  • 6
  • 50
  • 92
Vpaladino
  • 320
  • 2
  • 12

1 Answers1

1

Q : Is it possible for a single ROUTER socket to send a request to a specific DEALER (Out of many) socket and the DEALER send the result of the request back to the ROUTER? And if it is possible, how can this be done?

No, this is to the best of my knowledge not possible - it tries a DEALER/ROUTER anti-pattern.

Q : is there a better combination of sockets to approach this?

Yes, this could be possible in a bit wild approach to manually-driven identity-frames in ROUTER/ROUTER.


In case one has never worked with ZeroMQ,
one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds"
before diving into further details


While one can tweak the ROUTER-side with identity tricks, your problem fails at the DEALER-side, where a fair-queue and round-robin policies destroy your wished-to-have 1:1-relation and the pairing of the JobREQ:ResultREP will fail.


A bit more global view into how these toys work inside :

ZeroMQ archetypes are smart and multi-layered inside, beyond of what you typically work with when calling any of the API methods. Some insight into (simplified, maybe oversimplified) inner work might help in this :

                                                                          +------------------------------+  
                                                                          | Formal Behavioural Archetype |
                                                                          |                              |
                                                                          |                       ROUTER |
                                                                          +------------------------------+
                                                                          | BEHAVIOUR Management         |
          +------------------------------+                                |                              |
          | Formal Behavioural Archetype |                                |     HWM'd messages Dropped(*)| *unless ZMQ_ROUTER_MANDATORY set
          |                              |                                |                              |
          |                       DEALER |                                |                              |
          +------------------------------+                       <===.recv()   served in FAIR-QUEUED mode|
          | BEHAVIOUR Management         |                       .send()===>   served by identityFRAME id|
          | on                           |                                +------------------------------+ 
          | no peers                     |                                | IDENTITY Based Routing Policy| +may preset  ZMQ_CONNECT_ROUTING_ID for one next .connect() transport-setup call (ref. API for details)
          | or                           |                                |  <--prepend peer-Id on.recv()| +see setting ZMQ_ROUTING_ID and ZMQ_ROUTING_HANDOVER (ref. API for details)
          | all HWM'd in MUTE-STATE !Drop|                                |  -->remove  peer-Id on.send()|
 .send()===>   served in ROUND-ROBIN mode|                                |    +Drop if peer not visible | *unless ZMQ_ROUTER_MANDATORY set
 <===.recv()   served in FAIR-QUEUED mode|                                +------------------------------+
          +------------------------------+                                | QUEUE Management Department  |
          | QUEUE Management Department :|                                |                              |
          |                            ::|                                |                          |hwm|
          |                           :::|                                |   |                  |   |...|
          |hwm|              |   |   |hwm|                                |   |                  |   |.. |
          |...|              |hwm|   |...|                                |   |                  |hwm|.  |
          |.. |              |...|hwm|.. |                                |hwm|                  |...|   |
          |.  |              |.. |...|.  |                                +-:-|------------------|-:-|-:-|
          +-:-|--------------|-:-|-:-|:::+                                | TRANSPORT Handling Department|
          | TRANSPORT Handling Department|                                |---+                  +-------|
          |-------+          +-----------|                                |tcp|                  | ipc   |
          | inproc|          | ipc       |                                |-:-|                  |-:---:-|
          |-:-----|          |-:---:--:::|                                |.C |                  |.C |.C |
          |.C |   |          |.C |.C |.B |                                +-o-|------------------+-o---o-+
          +-o-|---+----------+-o---o---O-+                                  |                      |   |
            |                  |   |   ^                                    |                      |   |
            |                  |   |   |                                    |                      |   +----------------------.connect()->------- ... may be a { ROUTER | DEALER | REQ }-socket
            |                  |   |   |                                    +----------------------|--------------------------.connect()->------- ..
            |                  |   |   +-<--.connect()---[ROUTER].02----<--------------------------+
            |                  |   |   +-<--.connect()---[ROUTER].07--- .....
            |                  |   |   +-<--.connect()------[REP].41--- ....
            |                  |   +--------.connect()->----[REP].18--- ...
            |                  +------------.connect()->-[ROUTER].51--- ..
            +-------------------------------.connect()->----[REP].17--- .  (+ REP.send() message <=== sent must consist of an empty message part, the delimiter, followed by one or more body parts. )
user3666197
  • 1
  • 6
  • 50
  • 92
  • 1
    Thanks for your thorough response! I've seen a lot of your other answers involving ZeroMQ and you've been an amazing resource. – Vpaladino Feb 26 '20 at 16:48
  • **Always welcome,** @Vpaladino - all the credits go to Martin SUSTRIK - The Father plus Pieter HINTJENS - The Enabler & Co-Father - you will learn a lot about the **Zen-of-Zero** from these Masters – user3666197 Feb 26 '20 at 18:15