python和scala之间的zeromq请求 - 回复模式

时间:2015-06-28 22:30:58

标签: python scala zeromq

我正在尝试使用python和scala之间的ZeroMQ Request-Reply Pattern实现请求 - 回复示例。 根据zmq文档提供的代码,我设法成功运行scala中的请求者和python中的服务器。

scala to python rrclient scalarrserver python

现在我正试图做相反的事情。 python中的请求者和scala中的replier。

python TO scala rrclient pythonrrserver scala

这是python客户端代码

$(function () {
     $('#container').highcharts({
         chart: {
             type: 'column'
         },
         xAxis: {
             categories: ['Case 1', 'Case 2', 'Case 3']
         },
         series: [{
             name: 'Type A',
             data: [10, 0, 0]
         }, {
             name: 'Type B',
             data: [15, 0, 0]
         }]
     });

     // Button handler
     $('#button').click(function () {
         var chart = $('#container').highcharts();
         chart.series[0].setData([10, 20, 30]);
         chart.series[1].setData([15, 20, 25]);
         this.disabled = true;
     });

 });

这是scala代码

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示例中,它表示它希望以0结尾的字符串作为c-string。

我已经尝试从python发送一个简单的字符串和一个以0结尾的字符串,但它们都没有用。

发送python:

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中接收:

socket.send(b"Hello")
//or
socket.send(b"hello\x00")

我做错了什么?我觉得这是与python字符串相关的东西,但我还是无法解决它。

3 个答案:

答案 0 :(得分: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

  6. 如zeromq(https://github.com/valotrading/zeromq-scala-binding)的scala绑定主页上的README.md所述

      

    ZeroMQ的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

答案 1 :(得分:0)

我认为这可能是文档中的问题,您<project> ... <build> ... <resources> <resource> <directory>src/test/config</directory> </resource> </resources> ... </build> ... </project> 是服务器,因此将scala bind更改为reciever而不是bind

connect

答案 2 :(得分:0)

您是否尝试使用阻止接收? E.g:

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")

重新记住这一点的简单方法是(主要)服务器绑定,而客户端连接。