I want to make a simple connection between a Python program and a Ruby program using ZeroMQ, I am trying to use a PAIR connection, but I have not been able.
This is my code in python (the server):
import zmq
import time
port = "5553"
context = zmq.Context()
socket = context.socket(zmq.PAIR)
socket.bind("tcp://*:%s" % port)
while True:
socket.send(b"Server message to client3")
print("Enviado mensaje")
time.sleep(1)
It does not display anything until I connect a client.
This is the code in Ruby (the client)
require 'ffi-rzmq'
context = ZMQ::Context.new
subscriber = context.socket ZMQ::PAIR
subscriber.connect "tcp://localhost:5553"
loop do
address = ''
subscriber.recv_string address
puts "[#{address}]"
end
The ruby script just freezes, it does not print anything, and the python script starts printing Enviando mensaje
B.T.W: I am using Python 3.6.9 and Ruby 2.6.5
What is the correct way to connect a zmq PAIR
between Ruby and Python?
It does not display anything until I connect a client.
Sure, it does not, your code imperatively asked to block until a PAIR/PAIR
delivery channel got happen to become able to deliver a message. As the v4.2+ API defines, the .send()
-method will block during all the duration of a "mute state".
When a
ZMQ_PAIR
socket enters the mute state due to having reached the high water mark for the connected peer, or if no peer is connected, then anyzmq_send
(3) operations on the socket shall block until the peer becomes available for sending; messages are not discarded.
May try non-blocking mode of sending ( always a sign of a good engineering practice to avoid blocking, the more in distributed-computing ) and better include also <aSocket>.close()
and <aContext>.term()
as a rule of thumb ( best with explicit .setsockopt( zmq.LINGER, 0 )
) for avoiding hang-ups and as a good engineering practice to explicitly close resources and release them back to the system
socket.send( b"Server message #[_{0:_>10d}_] to client3".format( i ), zmq.NOBLOCK )
Last but not least :
What is the correct way to connect a zmq
PAIR
between Ruby and Python?
As the API documentation explains:
ZMQ_PAIR
sockets are designed for inter-thread communication across thezmq_inproc
(7) transport and do not implement functionality such as auto-reconnection.
There is no best way to do this, as Python / Ruby are not a case of inter-thread communications. ZeroMQ has since v2.1+ explicitly warned, that the PAIR/PAIR
archetype is an experimental and ought be used only with bearing that in mind.
One may always substitute each such use-case with a tandem of PUSH/PULL
-simplex channels, providing the same comfort with a pair of a .send()
-only + .recv()
-only channels.