You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用无法连接Express Socket.io服务器求助

问题:Express后端与Android Socket.io连接失败

问题背景

使用Express编写后端,Java开发Android应用,尝试实现Socket.io通信,但Android应用无法连接服务器。后端已通过Postman验证可正常接收请求,Android端执行mSocket.connect()后无连接成功日志,后端也无Android端连接记录,已将localhost替换为IPv4地址。

后端Socket处理代码

import { Server } from "socket.io";
import { SOCKET_EVENTS } from "../../constants/socket.js";
import { getBlockchainBlock } from "../crypto/crypto.js";

const io = new Server(4000, {
  cors: {
    origin: "*",
  },
});

export const openSocket = () => {
  io.on(SOCKET_EVENTS.CONNECTION, async (socket) => {
    console.log("user connected! socket id:", socket.id);

    io.emit(SOCKET_EVENTS.NEW_TASK, {
      data: await getBlockchainBlock(),
    });

    socket.on(SOCKET_EVENTS.TASK_FINISHED, (data) => {
      console.log("User task is done with data:", data);
    });

    socket.on(SOCKET_EVENTS.DISCONNECT, () => {
      console.log("user disconnected! socket id:", socket.id);
    });
  });
};

Android端依赖与连接代码

依赖配置

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

连接实现代码

public class MainActivity extends AppCompatActivity {

    Socket mSocket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = findViewById(R.id.test);
        textView.setText("Some test");

        Emitter.Listener onNewTask = new Emitter.Listener() {
            @Override
            public void call(final Object... args) {
            }
        };
        Emitter.Listener taskFinished = new Emitter.Listener() {
            @Override
            public void call(final Object... args) {
                mSocket.emit("taskFinished", "Task is finished");
            }
        };

        try {
            mSocket = IO.socket("http://ipAddress:4000");
            mSocket.on("newTask", onNewTask);
            mSocket.on("connection", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    System.out.println("Connected to server!");
                }
            });
            mSocket.on("taskFinished", taskFinished);
            mSocket.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

    }
}

问题排查与解决方案

1. Socket.io版本不兼容

后端使用Socket.io v3+(从import { Server } from "socket.io"写法可判断),但Android端依赖的是2.0.0版本,两者协议不兼容,这是核心问题。

解决方法:
将Android端Socket.io客户端版本升级到与后端匹配的4.x版本:

implementation 'io.socket:socket.io-client:4.6.1'

2. Android端监听事件错误

Socket.io客户端没有connection事件,正确的连接成功事件是connect,原代码监听错误事件导致无日志输出。

解决方法:
修改监听事件为connect,同时注意Android更新UI需在主线程:

mSocket.on("connect", new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        runOnUiThread(() -> {
            System.out.println("Connected to server!");
        });
    }
});

3. 缺少网络权限

Android应用必须获取INTERNET权限才能发起网络请求,否则无法建立Socket连接。

解决方法:
在AndroidManifest.xml中添加权限:

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

4. 补充连接配置(可选)

若仍无法连接,可添加传输方式、重连等配置:

try {
    IO.Options options = new IO.Options();
    options.transports = new String[]{"websocket"}; // 强制使用websocket传输
    options.reconnection = true;
    
    mSocket = IO.socket("http://ipAddress:4000", options);
    // 其他监听事件
    mSocket.connect();
} catch (URISyntaxException e) {
    e.printStackTrace();
}

5. 确认网络可达性

确保Android设备与服务器在同一局域网,且服务器4000端口未被防火墙拦截。可通过Android浏览器访问http://ipAddress:4000/socket.io/,若返回{"code":0,"message":"Transport unknown"}则说明端口可访问。

内容的提问来源于stack exchange,提问作者Tamir Abutbul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:07:51