2

I'm working with Pupil Labs, a huge open source for eye/pupil tracking. The entire code is written in Python. The so-called Pupil Remote is based on 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.

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. 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. It works neither locally nor remotely.

Happy about any answer, since I stuck at this.

user3666197
  • 1
  • 6
  • 50
  • 92
Viktoria
  • 533
  • 2
  • 7
  • 24
  • have you completed the 2nd half of the root-cause elimination test, advocated in the Answer below? With what results? – user3666197 Mar 09 '18 at 16:52
  • Yes, I tried it. Without the Android API my code works fine, so it wasn't an issue because of the subscriber (event though: I put the subscription policy in `String gaze = "gaze"; subscriber.subscribe(gaze.getBytes(Charset.forName("UTF-8")));`). It's an issue from the android side because since I'm starting the app itself, it won't work anymore. Please relate to my other question about it (https://stackoverflow.com/questions/49178921/network-connection-to-external-python-server/49179369?noredirect=1#comment85378090_49179369), as far as I got a solution, I'll post it in here, too. – Viktoria Mar 10 '18 at 12:41
  • So, could you explicitly confirm, what was observed in the test case, when **(A)** a trivial python-PUB-test-mock-up sender was indeed sending **`aPubSOCKET.send("gaze:TesterMessage", zmq.DONTWAIT)`** in a loop **+(B)** the Android was connected & subscribed to knowingly all Topics by **`subscriber.subscribe( filterPermitANY.getBytes() );` +(C)** Android side was **not `subscriber.close();context.term();`** right after a first message arrival? This is an important step in debugging, so do not split and divert attention of the Community members & rather follow the steps one after another, ok? – user3666197 Mar 10 '18 at 13:11
  • @user3666197 No, you don't understand. Probably I didn't explain myself clear enough, sorry about that. Let's make it simpler: The ZMQ connection is correct in the way, which I implemented it. I followed you recommendation, but technically I didn't have to because my code turned out to be alright (as a standalone solution). But thanks anyway. The only thing, which causes issues is the Android app itself. – Viktoria Mar 10 '18 at 13:19
  • Negative, Viktoria, your explicit answer about the said test results is important. You confirmed to run the test, but so far, there is no statement about received result. **What was this test result?** i.e. did the Android-`SUB` indeed `.recv()` a test-text from a trivial python-`PUB` or not **if you say it was tested as said above ?** – user3666197 Mar 10 '18 at 13:30
  • 1
    @user3666197 Yes it did. I got all the data from the topic `gaze`. (Won't post it in here, because it's just too much data) – Viktoria Mar 10 '18 at 13:35
  • This confirmation is cardinal. Thanks. – user3666197 Mar 10 '18 at 13:38

2 Answers2

0

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.

Viktoria
  • 533
  • 2
  • 7
  • 24
-1

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

Like your mailbox will never get newspapers in, without first subscribing to any. :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á.

Having zero-warranty what python version is running on the opposite side, tweaking may take place for string-representation matching...

( Also recommended to setup LINGER to 1, that prevents from hanging terminations
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 )


[ 1 ] We have got confirmed the Android/ZeroMQ side is working fine

if the PUB-side was mocked by a plain python-PUB infinite-sender and the Android-SUB was subscribed to String filterPermitANY ="";

This makes the above claim "It's an issue from the android side" actually void if not misleading.


[ 2 ] Next comes the question why it still does not work?

And the answer is: because the above designed code does not follow the published principles, how to connect and use the 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 ).


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.

user3666197
  • 1
  • 6
  • 50
  • 92
  • I don't want to subscribe everything, basically just the `gaze` data. – Viktoria Mar 07 '18 at 19:12
  • Even if I subscribe everything, nothing will happen. Unfortunately it doesn't help. – Viktoria Mar 07 '18 at 20:19
  • @Viktoria **never give up a test being only in the middle of the cause-effect path**. The next step is then to start a separate process, a trivial python proxy-`PUB`-lisher, that indeed does send proper messages by calling `aPubSOCKET.send( "gaze:TesterMessage", zmq.DONTWAIT )` in an endless tester loop. This will show you, if the Android-side receiver is principally working or not. If the java-code receives test messages as expected, the problem is neither in ZeroMQ, nor in java-side of the code. – user3666197 Mar 07 '18 at 20:50