ZeroMQ ROUTER 套接字能否向特定的 DEALER 套接字发出自发的异步请求?

Can a ZeroMQ ROUTER socket make a spontaneous asynchronous request to a specific DEALER socket?

我正在阅读 ZeroMQ Guide 并看到以下关于 ROUTER 套接字和身份的段落:

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.

根据这段话,"you can only really reply to a message, not spontaneously talk to a peer",意思是ROUTER不能发消息给一个特定的DEALER,但下一句暗示如果你强制路由器套接字使用逻辑地址就可以:"However you can force the ROUTER socket to use a logical address in place of its identity"。这部分让我感到困惑,因为他们只是说你不能自发地从路由器向经销商发送消息,但现在他们声称你可以。如果你按照 this link 的指南,你会看到在这一段之后,他们说 "It works as follows",但是他们给出的步骤似乎并没有弄清楚如何发送一个从 ROUTER 到特定 DEALER 的自发消息和 return 对原始 ROUTER 的回复。

我的问题: 单个 ROUTER 套接字是否可以向特定的 DEALER (在许多套接字中)发送请求并且DEALER 将请求结果发送回 ROUTER?如果可能的话,如何做到这一点?

跟进问题:如果这不可能,是否有更好的套接字组合来解决这个问题?

下面是我的设计粗略图:

基本上,客户端向 1 个特定服务器发送请求,该服务器处理该请求,然后 return 将请求的结果发送给客户端。客户端现在有了那个结果,并且它知道它是在哪个服务器上处理的。

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?

不,据我所知这是不可能的 - 它尝试 DEALER/ROUTER 反模式。

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

是的,在 ROUTER/ROUTER.

中,这可以通过一种有点疯狂的方法来实现手动驱动的身份框架

如果你从未使用过 ZeroMQ,
你可能会喜欢先看看
,然后再深入了解更多细节


虽然可以使用身份技巧调整 ROUTER 端,但您的问题在 DEALER 端失败了,公平队列和循环策略破坏了您希望的-有 1:1-关系并且 JobREQ:ResultREP 的配对将失败。


更全面地了解这些玩具的内部工作原理:

ZeroMQ 原型是智能的,内部是多层的,超出了您在调用任何 API 方法时通常使用的功能。对(简化的,可能过于简单的)内部工作的一些洞察可能对此有所帮助:

                                                                          +------------------------------+  
                                                                          | 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. )