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

Android Oreo下Socket.IO客户端连接Node.js服务器遇xhr poll error求助

解决Android Socket.IO客户端与Node.js服务器的XHR Poll Error问题

看起来你遇到的XHR Poll Error大概率是客户端与服务器版本不兼容导致的,再加上Android Oreo的特性限制,咱们一步步来解决:

1. 版本不匹配是核心问题

你的Node.js服务器用的是Socket.IO 2.1.1,但Android客户端依赖的io.socket:socket.io-client:0.8.3是非常老旧的版本(对应Socket.IO服务器1.x系列),和2.x的服务器完全不兼容,这是连接失败的主要原因。

你需要把Android客户端依赖升级到和服务器版本匹配的系列,修改build.gradle:

// 对应Socket.IO 2.x服务器的客户端版本
implementation 'io.socket:socket.io-client:2.0.0'
// 必须搭配对应的engine.io-client
implementation 'io.socket:engine.io-client:2.0.0'

2. 修正Android端的连接代码

你的代码里用AsyncTask处理Socket连接完全没必要——Socket.IO客户端本身就是异步的,而且Android Oreo对后台线程有更严格的限制,同时还有几个细节要调整:

  • 先补全必要的权限,在AndroidManifest.xml里添加:
<uses-permission android:name="android.permission.INTERNET" />
<!-- Android 9+需要允许明文HTTP请求,因为你用的是http://地址 -->
<application
    ...
    android:usesCleartextTraffic="true">
    ...
</application>
  • 移除AsyncTask,直接在主线程初始化Socket(Socket.IO内部会处理异步逻辑),修正后的核心代码示例:
private Socket mSocket;
private static final String TAG = "MainActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    display_text = (TextView)findViewById(R.id.display_text);
    // ... 其他UI初始化代码

    try {
        // 配置Socket连接参数
        IO.Options options = new IO.Options();
        options.transports = new String[]{"polling", "websocket"}; // 显式指定传输方式
        mSocket = IO.socket("http://192.168.0.104:4444", options);
        
        // 注册事件监听
        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, onTimeoutError);
        mSocket.on("data", onNewMessage);
        
        // 发起连接
        mSocket.connect();
    } catch (URISyntaxException e) {
        Log.e(TAG, "Socket初始化失败: " + e.getMessage());
        e.printStackTrace();
    }
}

// Activity销毁时记得关闭连接,避免内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mSocket != null) {
        mSocket.disconnect();
        mSocket.off();
    }
}

// 你的事件监听回调可以保留,比如onConnect这些
private Emitter.Listener onConnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        runOnUiThread(() -> {
            Log.e(TAG, "onConnect");
            Toast.makeText(getApplicationContext(), "Client is connected", Toast.LENGTH_LONG).show();
        });
    }
};

3. 检查Node.js服务器配置

确保服务器允许跨域请求(客户端和服务器不在同一域名/IP下时必须配置),Socket.IO 2.x的配置示例:

const express = require('express');
const app = express();
const http = require('http').createServer(app);
// 配置跨域
const io = require('socket.io')(http, {
  cors: {
    origin: "*", // 开发环境可以用*,生产环境请指定具体域名
    methods: ["GET", "POST"]
  }
});

// 测试连接的示例代码
io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

http.listen(4444, () => {
  console.log('Server running on port 4444');
});

4. 排查其他可能的问题

  • 确认手机和服务器在同一个局域网内(你用的192.168.0.104是局域网IP,手机要连同一WiFi)
  • 检查服务器防火墙是否开放了4444端口
  • Android Oreo后台限制:测试时保持App在前台,避免后台被限制网络请求

按这些步骤调整后,应该能解决XHR Poll Error的问题。如果还有问题,可以打印更详细的错误日志,方便进一步排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:20:13