如何在 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进去游戏。
由于在我的实施方面建立正确,实际问题是防火墙,它只是阻止了连接。通过发布我的解决方案,我希望能够帮助这个问题的未来访问者。
我正在与 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 服务器收到任何数据。我将自己定位于
对任何答案都很满意,因为我一直坚持到这里。
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 )
.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进去游戏。
由于在我的实施方面建立正确,实际问题是防火墙,它只是阻止了连接。通过发布我的解决方案,我希望能够帮助这个问题的未来访问者。