Zeromq request-response pattern between python and scala
I am trying to implement a request-response example using the ZeroMQ request-response pattern between python and scala. Based on the code provided by zmq documentation, I was able to successfully start the requester in scala and the server in python.
scala In python rrclient scala and rrserver python
Now I am trying to do the opposite. Request in python and responder in scala.
python TO scala rrclient python and rrserver scala
Here is the python client code
import zmq
# Prepare our context and sockets
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5559")
# Do 10 requests, waiting each time for a response
for request in range(1,11):
socket.send(b"Hello")
message = socket.recv()
print("Received reply %s [%s]" % (request, message))
And here is the scala code
import org.zeromq.ZMQ import org.zeromq.ZMQ.{Context,Socket} object rrserver { def main(args : Array[String]) { // Prepare our context and socket val context = ZMQ.context(1) val receiver = context.socket(ZMQ.REP) receiver.connect("tcp://localhost:5559") while (true) { // Wait for next request from client // We will wait for a 0-terminated string (C string) from the client, // so that this server also works with The Guide C and C++ "Hello World" clients //IT BLOCKS HERE val request = receiver.recv (0) println(request) // In order to display the 0-terminated string as a String, // we omit the last byte from request // println ("Received request: [" + new String(request,0,request.length-1) // Creates a String from request, minus the last byte // + "]") // Do some 'work' // try { // Thread.sleep (1000) // } catch { // case e: InterruptedException => e.printStackTrace() // } // Send reply back to client // We will send a 0-terminated string (C string) back to the client, // so that this server also works with The Guide C and C++ "Hello World" clients // val reply = "World ".getBytes // reply(reply.length-1)=0 //Sets the last byte of the reply to 0 // receiver.send(reply, 0) } }
}
In the scala example, it says it expects a 0-terminated string as a c-string.
I've already tried sending a simple string from python and 0-terminated strings, but none of them worked.
sending to python:
socket.send(b"Hello")
//or
socket.send(b"hello\x00")
in scala:
//result is always null here val request = receiver.recv (0)
What I do? I feel like it has something to do with the python string, but I haven't been able to solve it yet.
source to share
I faced the same problem. Finally, I found that I was using the wrong version of ZeroMQ.
Below are the versions of the resources I am using:
-
scala -binding:
zeromq-scala-binding_2.11.0-M3-0.0.7
-
scala:
Scala-2.11.7
-
zeromq:
Stable Release 2.2.0
-
jnr:
jnr-constants-0.8.2
-
jna:
jna-3.0.9
As stated in the README.md on the zeromq binding scala home page ( https://github.com/valotrading/zeromq-scala-binding ) which
The scala binding for ZeroMQ is based on ZeroMQ 2.1.x ...
At the very beginning, I was using the latest zeromq 4.0.4 and I tried using py-zmq to send the message and use scala -zmq for the recv message. But I have always found that socket in scala receives nothing (returns null) ...
And then you will understand why http://doc.akka.io/docs/akka/2.3.9/java/zeromq.html puts a note that
The version of the zeromq-scala bindings currently in use is only compatible with zeromq 2; zeromq 3 is not supported.
By the way, I am implementing this using eclipse on windows.
!! Finally, welcome to use my version: https://github.com/zzxx-husky/zeromq-scala-binding
source to share
Have you tried using a blocking move instead? For example:.
val request = receiver.recv()
Also, you definitely need to tie one end and connect the other!
So on the python side do:
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.bind("tcp://*:5559")
On the scala side:
val context = ZMQ.context(1)
val receiver = context.socket(ZMQ.REP)
receiver.connect("tcp://localhost:5559")
An easy way to remember this is that (basically) the server communicates while the client is connecting.
source to share