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.

+3


source to share


3 answers


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

+1


source


I think it might be a problem in the docs, you are the bind

server, so change scala reciever

to bind

instead of connect

:



receiver.bind("tcp://localhost:5559")

      

0


source


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.

0


source







All Articles