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. )
我正在阅读 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. BecauseROUTER
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 theROUTER
. However you can force theROUTER
socket to use a logical address in place of its identity. Thezmq_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 specificDEALER
(Out of many) socket and theDEALER
send the result of the request back to theROUTER
? 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. )