Q : Does anybody have an idea why it does not arrive?
Oh sure I have.
There are a few principal points that govern how the ZeroMQ-based distributed-computing systems may and do work.
If you are new to using ZeroMQ or other its derivatives ( nanomsg et al ), be sure not to miss Pieter Hintjen's must read book "Code Connected. Volume 1".
There are two places, where missed (or principally undeliverable) messages may come:
- Not yet ready process, which is assumed to receive a message, being the first
- Not available resource (port) for a successful
.bind()
, being the second
Harsh network transport conditions related problems are not the case for localhost
-only ( vmci://
-virtualised of internal port-abstracted network ) experimentations
Curable:
def main():
context = zmq.Context()
socket = context.socket( zmq.REQ )
socket.setsockopt( zmq.LINGER, 0 ) # ALWAYS PREVENT BLOCKING
socket.setsockopt( zmq.IMMEDIATE, 1 ) # BLOCK UNTIL CONN-READY
#ocket.setsockpt( zmq.ZMQ_HANDSHAKE_IVL, ... ) # IF TWEAKING NETWORK-WIDE
# OR:
# a stone-age wait for the other part get started in a one-computer demo:
# sleep( 20 )
# :o)
socket.connect( "tcp://localhost:{}".format( 5560 ) )
print( "Will try to dispatch an object to Context() instance" )
socket.send_pyobj( "ok" )
print( ".send() method has returned from a blocking-call mode" )
...
#--------------------------------------------------------# ALWAYS
socket.close() # ALWAYS RELEASE RESOURCES
context.term() # ALWAYS RELEASE RESOURCES
# # ALWAYS (not all versions
# # have "friendly"
# # defeaults to rely
# # on others,
# # so be explicit)
#--------------------------------------------------------# ALWAYS
One side, obviously not necessarily the REP
, yet here it fits better, due to while
, must .bind()
, the other(s) just .connect()
to a known connection target:
def main():
context = zmq.Context()
socket = context.socket( zmq.REP )
socket.setsockopt( zmq.LINGER, 0 ) # ALWAYS PREVENT BLOCKING
socket.setsockopt( zmq.IMMEDIATE, 1 ) # BLOCK UNTIL CONN-READY
#ocket.setsockpt( zmq.ZMQ_HANDSHAKE_IVL, ... ) # IF TWEAKING NETWORK-WIDE
socket.bind( "tcp://localhost:{}".format( 5560 ) )
print( ".bind() ...")
try:
while True: # Wait for next request from client:
message = socket.recv_pyobj()
print( message )
except:
print( "EXC'd" )
finally:
#----------------------------------------------------# ALWAYS
socket.unbind( "tcp://localhost:{}".format( 5560 ) ) # ALWAYS RELEASE PORT
socket.close() # ALWAYS RELEASE RESOURCES
context.term() # ALWAYS RELEASE RESOURCES
# # ALWAYS (not all versions
# # have "friendly"
# # defeaults to rely
# # on others,
# # so be explicit)
#----------------------------------------------------# ALWAYS
Last but not least, this will start to work, yet it will hang in an infinite waiting, due to a perhaps missed principle of the REQ/REP
-behaviour archetype. One must ASK ( REQ.send()
-s ), the other one, who is to REPLY has to listen-up the question REP.recv()
, however it also has to ANSWER... REP.send("something")
before we may move forwards in two-step-tango for two and the ASKER has also to get the answer listened to REQ.recv()
.
Then and only then the ASKER can send another question by another REQ.send()
.
So, both your sending REQ
-parts, yet mainly the receiving REP
-part, inside infinite while True:{...}
loop has to get revised, in order to receive any second and further messages, even for cases when REQ
-s die after a single shot and never listen to any answer from REP
.