简体   繁体   English

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

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

I'm working with Pupil Labs , a huge open source for eye/pupil tracking. 我正在与Pupil Labs合作, 后者是用于眼睛/学生跟踪的巨大开源。 The entire code is written in Python. 整个代码都是用Python编写的。 The so-called Pupil Remote is based on ZeroMQ. 所谓的Pupil Remote是基于ZeroMQ的。

If I start running the Filter Messages everything is fine. 如果我开始运行过滤器消息,一切都很好。 For my purposes I need to "translate" Filter Messages into Java because I created an Android app, which should call a client, which has the purpose to serve as the python client. 出于我的目的,我需要将“ 过滤器消息 ”“翻译”为Java,因为我创建了一个Android应用程序,该应用程序应调用客户端,该客户端的目的是充当python客户端。

Here's what I've done so far: 到目前为止,这是我所做的:

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

Now as you can expect, why I'm asking you, nothing happens, I don't receive any data from the Pupil Labs server. 正如您所期望的,为什么我要问您,什么都没有发生,我没有从Pupil Labs服务器收到任何数据。 I oriented myself on this post , but unfortunately, it didn't work out for me. 我将自己定位为这篇文章 ,但不幸的是,它对我没有用。 Also the IP-Address and port are the same as on the server. IP地址和端口也与服务器上的相同。 It works neither locally nor remotely. 它既不在本地也不在远程工作。

Happy about any answer, since I stuck at this. 因为我坚持这个,所以对任何答案都很高兴。

Due to the correct establishment in terms of my implementation the actual issue was the firewall, which just blocked the connection. 由于按照我的实现方式正确建立,实际的问题是防火墙,防火墙刚刚阻止了连接。 By posting my solution I'm hopefully able to help future visitors of this question. 通过发布我的解决方案,我希望能够为这个问题的未来访客提供帮助。

The final solution, after having debugged the root-cause issue is below 调试了根本原因问题后的最终解决方案如下


Happy about having answer, you have to set a subscription Policy: 很高兴获得答案,您必须设置订阅政策:

ZeroMQ expects each SUB -side to first explicitly say, what this SUB -side wants to receive from PUB ( Yes, what it to subscribes to ). ZeroMQ期望每个SUB端首先明确说出该SUB端要从PUB接收的内容(是的,它要订阅的内容)。

Like your mailbox will never get newspapers in, without first subscribing to any. 就像您的邮箱永远不会进入报纸,而无需先订阅任何报纸。 :o) :o)

So setup an empty string "" in the subscriber and you are done: 因此,在订户中设置一个空字符串"" ,您就可以完成:

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

Voilá. Voilá。

Having zero-warranty what python version is running on the opposite side, tweaking may take place for string-representation matching... 具有零保证的是相反版本上运行的python版本,可能会进行调整以匹配字符串表示形式...

( Also recommended to setup LINGER to 1, that prevents from hanging terminations (也建议将LINGER设置为1,以防止终止终端
and preferably it is the best time to turn the process 最好是时候开始这个过程了
into using a non-blocking .poll() + .recv( ..., ZMQ_DONTWAIT ) in a soft-realtime maintained event-loop ) 在软实时维护的事件循环中使用无阻塞.poll() + .recv( ..., ZMQ_DONTWAIT )


[ 1 ] We have got confirmed the Android/ZeroMQ side is working fine [1]我们已经确认Android / ZeroMQ方面工作正常

if the PUB -side was mocked by a plain python- PUB infinite-sender and the Android- SUB was subscribed to String filterPermitANY =""; 如果PUB端被普通的python PUB无限发送器模拟,而Android SUB 订阅String filterPermitANY ="";

This makes the above claim " It's an issue from the android side " actually void if not misleading. 如果没有引起误解,以上声明“ 来自Android的问题实际上是无效的。


[ 2 ] Next comes the question why it still does not work? [2]接下来是为什么它仍然不起作用的问题?

And the answer is : because the above designed code does not follow the published principles , how to connect and use the Pupil Labs API. 答案是 :因为上面设计的代码不遵循已发布的原理 ,所以如何连接和使用Pupil Labs API。

A careful reader will notice that the Pupil Labs API is not connected by the SUB -side ( be it an Android or python or whatever else implementation of such a peer ) on a port :50020 , but on another port, which is first asked about via another dialogue, held over an REQ/REP -formal communication archetype ( lines 13/14/15+19 ). 细心的读者会注意到,在端口:50020不是SUB端(无论是Android还是python或此类对等方的任何其他实现)上, Pupil Labs API都已连接,而是在另一个端口上首先连接了该端口通过另一个对话,该对话在REQ/REP正式沟通原型中进行( lines 13/14/15+19 13/14/15 lines 13/14/15+19 )。


Epilogue 结语

Knocking on a wrong door will never make the intended interview happen. 敲错门永远不会使预定的采访发生。

One first has to ask onto which door to knock next, so as to get the Pupil Labs API into the game. 首先,必须询问要敲哪扇门,才能将Pupil Labs API纳入游戏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM