'Android socket.io application can't connect to node.js server

my application, using socket.io, cant connect to node.js server.

server node.js

var app = require('http').createServer()
var io = require('socket.io')(app);

app.listen(1000);

io.on('connection', function (client) { 

  client.name = client.remoteAddress + ':' + client.remotePort;
  console.log(client.name + ' connected!'); 

    client.on('sensorChanged', function (data) {
        console.log("HERE");
        console.log(data);
    });

});

android application:

    SocketIO socket = new SocketIO();
    try {
        socket.connect("http://localhost:1000/", this);
        txtView.setText("connected");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    socket.emit("sensorChanged", "argument1");

When i connect to the server, server doesnt say "socket.name connected", and doesnt emit event 'sensorChanged'. Where is the problem?



Solution 1:[1]

I also had connectivity issues when connecting Android app with Socket.IO with my server on the same WiFi (despite the fact that the connection worked when I tried to connect to the same URL in browser).

I found the solution here: https://stackoverflow.com/a/50834600/9560885

In short, try adding this line to your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

Solution 2:[2]

Use IP address: 10.0.2.2 for AVD & 10.0.2.3 for genymotion.

If you are using an external device on the same network, then use your server machine's local IP address.

Solution 3:[3]

Establishing Socket.IO Connection from Android Device to Local Node Server


A. Make sure you've installed socket.io-client-java via gradle.


B. Make sure you've enable internet access for your device.

<!-- AndroidManifest.xml -->

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="...">

    <uses-permission android:name="android.permission.INTERNET" />

    <application ...>
        ...
    </application>
</manifest>

C. Make sure the port you're running the server on is open.


D. Connect to your local server using your computers network ip address.

  • Open a terminal.
  • Enter the command ipconfig.
  • Look for your IPv4 Address.

You want to connect to http://<IPv4 Address>:<port>.

Connecting to localhost via http://localhost:3000 will not work because 'localhost' refers to the device itself.


E. Test the connection on your device.

  • Set up a simple route on your server GET /status that just returns 200.
  • Navigate to http://<IPv4 Address>:<port>/status on your device.
  • If you get a success response, you should be good to go.

F. You should now be able to connect your android socket client to your node socket server.

// Node.js App

let SocketIO = require('socket.io');

let ioServer = SocketIO(server);
console.log('Socket Server waiting for connections');

ioServer.on('connection', function (socket) {
    console.log(`Socket Client connected with id=${socket.id}`);
});

-

// Android App

import io.socket.client.Socket;
import io.socket.client.IO;
import io.socket.emitter.Emitter;
import android.util.Log;

public class SocketIO implements Runnable {
    @Override
    public void run() {

        final Socket socket;

        try {
            socket = IO.socket("http://<IPv4 Address>:<port>");

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {
                    Log.d("TAG", "Socket Connected!");
                    socket.disconnect();
                }

            });

        } catch(Exception e){
            Log.e("Error", e.toString());
        }

    }
}

Solution 4:[4]

Sorry for the late answer, I've just found the same condition, which makes me confused about what should I'm doing to solve this weird condition

All I did to solve this problem is just changing the version of the socket.io of the node server on your package.json

from

"dependencies": {
  "express": "^4.17.1",
  "socket.io": "^3.1.1"
}

to

"dependencies": {
  "express": "^4.17.1",
  "socket.io": "^1.7.2"
}

then delete the node_modules and execute npm install, or you can do any kind of way for decreasing the socket.io to ^1.7.2 version

Solution 5:[5]

Check this out, worked for me with the line below:

opts.transports = new String[]{"websocket"};

https://stackoverflow.com/a/67978895/6909832

Solution 6:[6]

My android application and nodejs was just connecting but not sending or receiving anything, then i have solved this issue by downgrading from

2.0.0 to 0.8.3 version in gradle file

implementation ('io.socket:socket.io-client:2.0.0') { 
    exclude group: 'org.json', module: 'json'
}

to

implementation ('io.socket:socket.io-client:0.8.3') { 
    exclude group: 'org.json', module: 'json'
}

and it worked for me

Solution 7:[7]

You are targeting Node server on your local machine from android. Since node does not run on Android (as far as I know) I am guessing you wanted to target the server on your pc. Instead of localhost(which in this Android code would refer to phone/tablet itself) you should use the network address of your pc in your local network.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luka Kralj
Solution 2 Sᴀᴍ Onᴇᴌᴀ
Solution 3 Derek Soike
Solution 4
Solution 5 Matheus Santz
Solution 6 Osama Zafar
Solution 7 Igor ?ordaš