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
相关产品推荐
相关产品推荐

