如何在 Java SUB 客户端 (ZMQ) 上从 python ZeroMQ PUB 服务器接收数据

How to receive data from a python ZeroMQ PUB server on a Java SUB client (ZMQ)

我正在与 Pupil Labs 合作,这是一个巨大的 eye/pupil 跟踪开源软件。整个代码写在Python中。所谓Pupil Remote是基于ZeroMQ的

如果我开始 运行 Filter Messages everything is fine. For my purposes I need to "translate" 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 服务器收到任何数据。我将自己定位于 ,但不幸的是,它对我没有用。 IP 地址和端口也与服务器上的相同。它既不在本地也不在远程工作。

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

The final solution, after having debugged the root-cause issue is below


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

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() );           //     

瞧瞧。

对面有 zero-warranty python 版本 运行,可能需要调整 string-representation 匹配...

( 还建议将 LINGER 设置为 1,以防止挂起终端
而且最好是转流程的最佳时机
在 soft-realtime 维护 event-loop )

中使用 non-blocking .poll() + .recv( ..., ZMQ_DONTWAIT )

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

如果 PUB 端被普通的 python-PUB infinite-sender 和 Android-SUB 订阅了String filterPermitANY ="";

这使得上述 如果没有误导的话实际上是无效的。


[ 2 ] 接下来问题来了,为什么还是不行?

而答案是:因为上面设计的代码没有遵循公开的原则,如何连接和使用学生实验室 API.

细心的reader会注意到 Pupil Labs API 不是SUB 端连接(可以是 Android 或 python 或此类对等端的任何其他实现)一个端口 :50020,但在另一个端口上,它首先通过另一个对话询问,保留在 REQ/REP 上- 正式的沟通原型 ( lines 13/14/15+19 ).


结语

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

先问问接下来敲哪扇门,才能让Pupil LabsAPI进去游戏。

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