【问题标题】:How to receive data from a python ZeroMQ PUB server on a Java SUB client (ZMQ)如何在 Java SUB 客户端 (ZMQ) 上从 python ZeroMQ PUB 服务器接收数据
【发布时间】:2018-03-11 02:54:47
【问题描述】:

我正在与 Pupil Labs 合作,这是一个用于眼睛/瞳孔跟踪的大型开源软件。整个代码是用 Python 编写的。所谓Pupil Remote是基于ZeroMQ的。

如果我开始运行Filter Messages,一切都很好。出于我的目的,我需要将Filter Messages“翻译”成 Java,因为我创建了一个 Android 应用程序,它应该调用一个客户端,该客户端的目的是充当 python 客户端。

这是我到目前为止所做的:

import android.annotation.SuppressLint;
import org.zeromq.ZMQ;
import java.nio.charset.Charset;
import static java.lang.Thread.sleep;

public class ZeroMQClient {
    @SuppressLint("NewApi")
    public static void requestGazeData() {

        ZMQ.Context context = ZMQ.context(1);
        ZMQ.Socket subscriber = context.socket(ZMQ.SUB);

        System.out.println("Connecting to server...");

        subscriber.connect("tcp://xxx.x.x.x:50020");

        System.out.println("Connected");

        String gaze = "gaze";
        subscriber.subscribe(gaze.getBytes(Charset.forName("UTF-8")));

        while (true) {
            String msg = subscriber.recvStr();
            System.out.println(msg);

            subscriber.close();
            context.term();
        }
    }
}

现在正如你所料,为什么我要问你,什么也没发生,我没有从 Pupil Labs 服务器收到任何数据。我把自己定位在this post,但不幸的是,它对我没有用。 IP地址和端口也与服务器上的相同。它既不能在本地工作,也不能在远程工作。

对任何答案都很满意,因为我坚持这一点。

【问题讨论】:

  • 您是否完成了下面的答案中提倡的根本原因消除测试的第二部分?结果如何?
  • 是的,我试过了。如果没有 Android API,我的代码可以正常工作,所以这不是因为订阅者的问题(尽管事件:我将订阅策略放在 String gaze = "gaze"; subscriber.subscribe(gaze.getBytes(Charset.forName("UTF-8"))); 中)。这是 android 方面的一个问题,因为由于我正在启动应用程序本身,所以它不再工作了。请联系我的其他问题(stackoverflow.com/questions/49178921/…),只要我有解决方案,我也会在这里发布。
  • 那么,您能否明确确认,当 (A) 一个琐碎的 python-PUB-test-mock-up 发件人确实发送 (A) 时,您可以明确确认在测试用例中观察到的情况b>aPubSOCKET.send("gaze:TesterMessage", zmq.DONTWAIT) 在循环中 +(B) Android 已连接并订阅了 subscriber.subscribe( filterPermitANY.getBytes() ); +(C) Android 端的所有主题在第一条消息到达之后不是subscriber.close();context.term();吗?这是调试的重要一步,所以不要分散和转移社区成员的注意力,而是一个接一个地执行,好吗?
  • @user3666197 不,你不明白。可能我解释得不够清楚,抱歉。让我们让它更简单:ZMQ 连接方式是正确的,我实现了它。我遵循了您的建议,但从技术上讲,我不必这样做,因为我的代码结果很好(作为独立解决方案)。不过还是谢谢。唯一会导致问题的是 Android 应用程序本身。
  • @user3666197 是的。我从主题gaze 中获得了所有数据。 (这里就不贴了,数据太多了)

标签: java android zeromq


【解决方案1】:

由于我的实现正确建立,实际问题是防火墙,它只是阻止了连接。通过发布我的解决方案,我希望能够帮助这个问题的未来访问者。

【讨论】:

  • 感谢您分享您的答案,我希望这对其他人也有帮助!
【解决方案2】:

在调试了根本原因问题后的最终解决方案如下


很高兴有答案,您必须设置订阅政策:

ZeroMQ 希望每个SUB 方首先明确地说,SUB 方希望从 PUB 接收什么>(是的,它要订阅什么)。

就像您的邮箱永远不会收到报纸一样,如果没有先订阅任何报纸。 :o)

所以在订阅者中设置一个空字符串 "" 就完成了:

// String                filterPermitANY = "";        // WAS AN EXAMPLE TO TEST
// subscriber.subscribe( filterPermitANY.getBytes() );//     IF PUB.send()-s ANY
   String                gaze = "gaze";               // WAS ON TOPIC
   subscriber.subscribe( gaze.getBytes() );           //     

瞧。

由于对面运行的 python 版本是零保证的,因此可能会针对字符串表示匹配进行调整...

( 还建议将LINGER 设置为 1,以防止挂起终端
最好是转过程的最佳时机
在软实时维护的事件循环中使用非阻塞.poll() + .recv( ..., ZMQ_DONTWAIT )


[ 1 ] 我们已经确认 Android/ZeroMQ 端工作正常

如果 PUB 端被普通的 python-PUBfinite-sender 模拟并且 Android-SUB 订阅了 String filterPermitANY ="";

这使得上面的claim "It's an issue from the android side" 如果没有误导的话实际上是无效的。


[ 2 ] 接下来是为什么它仍然不起作用的问题?

而答案是:由于上面设计的代码没有遵循公布的原则,如何连接和使用Pupil Labs API .

细心的读者会注意到 Pupil Labs API 没有通过 SUB 连接-在端口 :50020 上的一侧(无论是 Android 还是 python 或其他任何此类对等体的实现),但在另一个端口上,首先通过另一个对话询问,通过 REQ/REP-正式沟通原型(lines 13/14/15+19)。


结语

敲错门永远不会实现预期的采访。

首先必须询问接下来要敲哪扇门,以便将 Pupil Labs API 放入游戏中。

【讨论】:

  • 我不想订阅所有内容,基本上只是 gaze 数据。
  • 即使我订阅了所有内容,也不会发生任何事情。不幸的是,它没有帮助。
  • @Viktoria 永远不要放弃仅在因果路径中间的测试。下一步是启动一个单独的进程,一个简单的 python 代理-PUB-lisher,它确实通过在无休止的测试器循环中调用aPubSOCKET.send( "gaze:TesterMessage", zmq.DONTWAIT ) 发送正确的消息。这将向您显示 Android 端接收器是否主要工作。如果 java 代码按预期接收到测试消息,则问题既不在 ZeroMQ 中,也不在代码的 java 端。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2019-08-13
  • 2017-12-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多