Flutter用Adhara库连Socket.IO报EngineIOException: websocket error排查
我尝试通过Adhara Flutter库连接Socket.IO服务器,按照官方建议在项目的pubspec.yaml中添加依赖后,编写了如下连接代码:
@override void initState() { super.initState(); manager = SocketIOManager(); initSocket(); } initSocket() async { SocketIO socket = await manager.createInstance(SocketOptions('https://socket.******.ir')); socket.onConnect((data) { debugPrint("connected..."); debugPrint(data); }); socket.onConnectError((er) { debugPrint('onConnectError: $er'); }); socket.onConnectTimeout((er) { debugPrint('onConnectTimeout: $er'); }); socket.onError((er) { debugPrint('onError: $er'); }); socket.onDisconnect((er) { debugPrint('onDisconnect: $er'); }); socket.connect(); }
运行后反复出现以下错误:
Syncing files to device Android SDK built for x86... I/flutter ( 6791): onConnectError: io.socket.engineio.client.EngineIOException: websocket error
我已经通过Socket.IO Tester Chrome扩展验证服务器是正常的,发送test事件可以收到响应;并且已经在AndroidManifest.xml的application标签内添加了android:useCleartextTraffic="true"。请问这个Flutter连接问题的原因是什么?
我来帮你分析下可能的原因,结合你已经做的排查,从几个方向入手:
1. Socket.IO版本不兼容是重灾区
Adhara这个库对Socket.IO服务器的版本要求特别严格,比如早期版本的Adhara只支持Socket.IO v2.x,如果你的服务器是v3或者v4版本,两者的协议不匹配,必然会出现websocket连接失败的错误。
- 解决办法:
- 先查下你用的Adhara版本对应的服务器版本要求(去pub.dev搜
adhara_socket_io就能看到说明); - 如果服务器版本太高,要么降级服务器到兼容的版本,要么换用Adhara支持高版本的分支(不过注意有些分支可能改了API,需要调整代码)。
- 先查下你用的Adhara版本对应的服务器版本要求(去pub.dev搜
2. HTTPS证书信任问题
你用的是HTTPS地址,Android设备默认会校验服务器的SSL证书,如果是自签名证书或者证书不被系统信任,WebSocket握手就会失败。
- 解决办法:
- 测试环境可以先临时禁用证书验证(生产环境绝对不能这么干),修改SocketOptions:
SocketOptions options = SocketOptions('https://socket.******.ir', config: { 'transports': ['websocket'], 'rejectUnauthorized': false // 关闭证书校验 } ); SocketIO socket = await manager.createInstance(options); - 生产环境的话,要把服务器的SSL证书配置成受信任的,或者在Android项目中添加自定义证书信任。
- 测试环境可以先临时禁用证书验证(生产环境绝对不能这么干),修改SocketOptions:
3. 传输方式不匹配
Adhara默认可能会先尝试polling传输,再切换到websocket,但有些服务器可能只开启了websocket,或者你的网络环境限制了polling方式,导致连接失败。
- 解决办法:
- 强制指定只用websocket传输,在SocketOptions里加上配置:
SocketOptions options = SocketOptions('https://socket.******.ir', config: { 'transports': ['websocket'], // 只使用websocket } );
- 强制指定只用websocket传输,在SocketOptions里加上配置:
4. 服务器端CORS配置问题
虽然Chrome插件能连接,但Flutter客户端的请求可能触发了服务器的CORS限制,尤其是当你的应用在本地调试时,域名/IP不在服务器的允许列表里。
- 解决办法:
- 检查服务器端的Socket.IO CORS配置,确保允许你的Flutter应用的来源访问,比如Node.js服务器可以这么配置:
const io = require("socket.io")(server, { cors: { origin: "*", // 测试环境用*,生产环境要指定具体域名 methods: ["GET", "POST"] } });
- 检查服务器端的Socket.IO CORS配置,确保允许你的Flutter应用的来源访问,比如Node.js服务器可以这么配置:
5. Adhara库本身的兼容性问题
实话实说,Adhara这个库已经很久没更新了,可能和新版本的Flutter或者Android系统存在兼容性bug。如果上面的方法都没用,可以考虑换用更活跃的Socket.IO客户端库,比如官方推荐的socket_io_client,这个库维护得更频繁,兼容性更好。
内容的提问来源于stack exchange,提问作者Cyrus the Great

