2

I'm trying to create a simple chat using Socket IO, Android and Node. When I run the app and try to connect to the server, it always fails with a timeout error and I can't figure out why.

Here's the Node code:

app = require('express')()
http = require('http').createServer(app)
io = require('socket.io')(http)

app.get('/', (req,res) => {

    res.send('Chat server is running on port 5000')
})

/**
 * Defines a listener to an event called connection and this event will be fired from the client side
 */
io.on('connection', (socket) => {

    console.log('user connected')
})

http.listen(5000, () => {

    console.log('Node app is running on port 5000')
})

Here's the Android code (Editted according to Marcos Casagrande Answer:

import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.engineio.client.transports.WebSocket;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    Intent intent = getIntent();
    if(intent.hasExtra(NICKNAME)){

        mNickname = intent.getStringExtra(NICKNAME);
        Log.d(TAG, "chatapp onCreate: " + mNickname);
    }

    try {

        IO.Options opts = new IO.Options();
        opts.transports = new String[]{WebSocket.NAME};
        mSocket = IO.socket("http://10.0.0.21:5000", opts);

        mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.d(TAG, "chatapp call: connected to server");
            }
        });

        mSocket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.d(TAG, " chatapp call: disconnected from the server");
            }
        });

        mSocket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.d(TAG, "chatapp call: connection error");
            }
        });

        mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.d(TAG, "chatapp call: connection timeout");
            }
        });

        mSocket.connect();

    } catch (Exception e) {
        Log.d(TAG, "onCreate: something unexpected happened");
        e.printStackTrace();
    }

I try to run the app on virtual device through Android Studio I keep getting Connection timeout error. Can someone tell me, what am I doing wrong?

Keselme
  • 3,779
  • 7
  • 36
  • 68

2 Answers2

4

The connection won't happen instantly, it's asyncrhonous, attach the correct handlers and check for connection or errors in there.

mSocket = IO.socket("http://localhost:5000");

mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);

mSocket.connect();
// ....

private Emitter.Listener onConnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        Log.d(TAG, "connected...");
        // This doesn't run in the UI thread, so use: 
        // .runOnUiThread if you want to do something in the UI

    }
};

private Emitter.Listener onConnectError = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        Log.d(TAG, "Error connecting...");
    }
};

I recommend using WebSocket transport in android, to avoid polling errors, you can check my answer here:

How to set transports for SocketIO in Android?

Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • 1
    Thanks, I changed the code according to your suggestion. However, I still get an error `xhr poll error`. I still will accept your answer though, because it helped me to move forward with my problem. – Keselme Nov 30 '19 at 15:34
  • 1
    You should probably avoid using long polling in android, use `websocket` transport. Check my other answer here for that: https://stackoverflow.com/questions/44015305/how-to-set-transports-for-socketio-in-android/44023957#44023957 – Marcos Casagrande Nov 30 '19 at 15:38
  • Do you see the connection in the server? – Marcos Casagrande Nov 30 '19 at 16:05
  • Nope, I dont see any logs on the server. I see only the `listen` message – Keselme Nov 30 '19 at 16:10
  • You're using a private IP, are you sure your phone has access to that IP? go to your phone browser and go to that URL: `"http://10.0.0.21:5000"` – Marcos Casagrande Nov 30 '19 at 16:12
  • I'm running it on the emulator, regardless, when I try to go in the browser to `http://10.0.0.21:5000` I get connection refused error – Keselme Nov 30 '19 at 16:16
  • Then that's not the IP you have to use, that's why you get that error, use the public IP: `192.168.1.x` most likely. – Marcos Casagrande Nov 30 '19 at 16:23
0

You have to use 2 AVD's instead of physical devices to connect with this IP. If now try with http://10.0.2.2:5000

Sanush
  • 305
  • 1
  • 4
  • 14