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.