Python和Scala之间的ZeroMQ请求-响应模式

3
我正在尝试使用ZeroMQ Request-Reply Pattern在Python和Scala之间实现请求-响应示例。基于ZMQ文档提供的代码,我成功地在Scala中运行了请求者并在Python中运行了服务器。
从scala到python: rrclient scalarrserver python 现在我想做相反的事情。一个Python请求者和一个Scala回复者。
从python到scala: rrclient pythonrrserver scala 这是Python客户端代码。
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))

这里是Scala代码

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's 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's 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)
    }
}

}

在Scala示例中,它要求以0结尾的字符串作为c字符串。
我已经尝试从Python发送简单字符串和0结尾的字符串,但都没有成功。
在Python中发送:
socket.send(b"Hello")
//or
socket.send(b"hello\x00")

在Scala中接收:

//result is always null here
val request = receiver.recv (0)

我做错了什么?我觉得这与Python字符串有关,但我还没有解决它。

你是怎么安装Scala绑定的?我无法在Scala 2.11上使用它。你用了哪个依赖项?谢谢! - Andriy Drozdyuk
3个回答

1
我遇到了同样的问题。最后我发现我使用了错误版本的ZeroMQ。
以下是我使用的资源版本:
  1. scala-binding: zeromq-scala-binding_2.11.0-M3-0.0.7

  2. scala: Scala-2.11.7

  3. zeromq: Stable Release 2.2.0

  4. jnr: jnr-constants-0.8.2

  5. jna: jna-3.0.9

如在scala binding of zeromq的主页README.md中所述(https://github.com/valotrading/zeromq-scala-binding),Scala绑定ZeroMQ基于版本2.1.x...
在最开始的时候,我使用了zeromq 4.0.4的最新版本,并尝试使用py-zmq发送消息以及使用scala-zmq接收消息。但我发现scala中的socket始终没有接收到任何消息(返回null)... 然后你就会明白为什么http://doc.akka.io/docs/akka/2.3.9/java/zeromq.html会注明:

当前使用的zeromq-scala-bindings版本只与zeromq 2兼容;不支持zeromq 3。

顺便说一下,我是在Windows上使用Eclipse实现的。 最后,欢迎使用我的版本:https://github.com/zzxx-husky/zeromq-scala-binding

0
你尝试过使用阻塞接收吗?例如:
val request = receiver.recv()

此外,你肯定需要将一端进行绑定,另一端进行连接!
因此,在 Python 端执行以下操作:
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.bind("tcp://*:5559")

在Scala方面:

val context = ZMQ.context(1)
val receiver = context.socket(ZMQ.REP)
receiver.connect("tcp://localhost:5559")

记住这个简单的方法,即(大多数情况下)服务器绑定,而客户端连接。


0

我认为这可能是文档中的问题,你需要将服务器进行绑定(bind),所以请将你的Scala接收器(receiver)更改为bind而不是connect

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

我已经尝试按照您的建议使用bind,但行为仍然相同。它没有接收到任何消息。 - Arian Pasquali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接