1

I'm trying to do a test with Jeromq library with a simple app which doesn't work.

Here's Server :

import org.zeromq.ZMQ;

public class Server  {

     public static void main(String[] args) throws Exception {

            ZMQ.Context ctx = ZMQ.context(1);

            ZMQ.Socket socket = ctx.socket(ZMQ.REP);
            socket.bind("tcp://192.168.56.1:5570");
            System.out.println("Started");

            while (!Thread.currentThread().isInterrupted()) {

                byte[] request = socket.recv(0);
                String string = new String(request);
                System.out.println("Received request: ["+string+"].");

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                socket.send("We got message".getBytes(), 0);
            }

            System.out.println("finished");
            socket.close();
            ctx.term();           
     } 
}

So, after starting it I have a Log - "Started". 192.168.56.1 is my local ip address and netstat -na (I'm working on Windows) shows me that 192.168.56.1:5570 is Listening. So, I guess it's ok. I opened this socket in Windows.

Then on android I wrote this :

Interface for connection establishing :

public interface ConnectionReadyListnener {

        void onServerConnectionEstablished();

}

Then Connection AsyckTask to establish connection to th server :

public class Connection extends AsyncTask<Void, Void, Void> {

    public ConnectionReadyListnener listener=null;
    public static ZMQ.Context context;
    public static ZMQ.Socket socket;


    @Override
    protected Void doInBackground(Void... params) {

        context = ZMQ.context(1);
        socket = context.socket(ZMQ.DEALER);
        socket.setIdentity("12345".getBytes(ZMQ.CHARSET));
        socket.connect("tcp://192.168.56.1:5570"); 

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        listener.onServerConnectionEstablished();
    }

}

and MainActivity that launches test task when connection is established:

public class MainActivity extends Activity implements ConnectionReadyListnener{
    Connection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        connection = new Connection();
        connection.listener=this;
        connection.execute();
    }

    @Override
    public void onServerConnectionEstablished() {
        Toast.makeText(getApplicationContext(), "connected", Toast.LENGTH_SHORT).show();
        new TestAsynk().execute();

    }


}

And here's the TestAsynk class to send a test message that server should recieve and Log to the console :

public class TestAsynk extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        Connection.socket.send("Test".getBytes(), 0);
        return null;
    }

}

But it never logs the result out - it doesn't receive it. The problem is I don't know why - phone (real device) and computer with server are within one WiFi network. And also I learned that there is no way For ZeroMQ to find out if the connection is really established or not.

Please help me figure it out .

Vlad Alexeev
  • 2,072
  • 6
  • 29
  • 59
  • Did you find a solution to this issue? I am stuck with this for the last two days with not much help from google. – Ashok Nov 17 '16 at 12:35
  • @Ashok sorry, I didn't and quit trying ZMQ. Also, tests shown that websockets are faster than zmq – Vlad Alexeev Nov 17 '16 at 15:31
  • oh ok. Thanks for the response anyway. It seems a colleague of mine has already done this successfully. Will update here if so. – Ashok Nov 18 '16 at 04:07
  • I was missing the INTERNET permission in the Android Manifest. It was also not reported in the logs for some reason! Could this have been the reason why it was also not working for you ?? `_Thanks to [https://www.novoda.com/blog/minimal-zeromq-client-server] blog post. It mentions the permission on the last line. Reading between the lines is not enough sometimes :)_` – Ashok Nov 18 '16 at 07:04
  • no, I had this permission, and I had a problem on a server side – Vlad Alexeev Nov 18 '16 at 08:08

1 Answers1

0

There a quite a few problems here.

1) NEVER NEVER NEVER pass a socket between threads. The only threadsafe object in ZeroMQ is the Context. Passing a socket between threads almost definitely the source of the problem here.

2) If you had a problem on the server side, it could be that the IP address is incorrect. If possible, I would not recommend hard coding the IP address on the side which binds. Just use the wildcard "*" instead. So on the server side, it would look like

    socket.bind("tcp://*:5570");

3) Your Async pattern has a glaring error... What would happen if onPostExecute ran before listener was set to the Activity? At the very least, add a constructor to your AsyncTask that takes in the Activity...something like

public Connection(Activity listener){
    this.listener = listener;
}

4) Check the permissions. In the past, I have required both the INTERNET and ACCESS_WIFI_STATE permissions.

bremen_matt
  • 6,902
  • 7
  • 42
  • 90