Flutter WebSocket在Web端可正常连接但Android模拟器无法连接怎么解决
问题成因
- Android应用网络权限缺失:Web端运行在浏览器环境下默认具备网络访问权限,而Android原生应用默认未授予网络访问权限,未配置权限时会直接拦截所有外网请求。
- 模拟器网络连通性异常:模拟器自身网络配置错误、代理设置拦截、DNS解析失败等问题都会导致WebSocket连接失败,部分默认模拟器的网络隔离策略也会影响和公网服务的连通。
- 证书信任规则差异:Android系统对TLS证书的校验规则比浏览器严格,若目标服务使用的是自签名证书、过期证书或者不在系统信任根证书列表内的证书,会直接中断TLS握手,而Web端如果用户手动信任过对应证书则可正常访问。
- 底层实现兼容问题:Web端
web_socket_channel调用的是浏览器原生WebSocket API,安卓端调用的是Dart原生IO库实现,部分旧版本的依赖库存在wss握手SNI不兼容、握手超时设置过短等已知问题。
解决方法
- 配置Android网络权限
在项目路径android/app/src/main/AndroidManifest.xml的<manifest>根标签下,添加网络权限声明:
<uses-permission android:name="android.permission.INTERNET" />
如果需要监听网络状态,可额外添加<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />。
修复模拟器网络问题
- 先打开模拟器自带的浏览器,直接访问WebSocket测试地址,确认模拟器本身可正常连通目标服务
- 若连接的是本地搭建的WebSocket服务,不要使用
127.0.0.1或者localhost,替换为安卓模拟器访问宿主机的专属地址10.0.2.2 - 关闭模拟器的代理配置,切换模拟器网络为桥接模式,或重启模拟器后重试。
适配证书校验规则
如果是测试环境使用自签名证书,可临时配置信任所有证书,该配置禁止在生产环境使用:
import 'dart:io'; import 'package:web_socket_channel/io.dart'; // 仅测试环境使用 HttpClient httpClient = HttpClient(context: SecurityContext.defaultContext); httpClient.badCertificateCallback = (X509Certificate cert, String host, int port) => true; final channel = IOWebSocketChannel.connect( Uri.parse('wss://echo.websocket.org'), customClient: httpClient, );
生产环境请将服务端证书添加到安卓应用的信任证书列表内,避免关闭证书校验带来的安全风险。
升级依赖版本
将pubspec.yaml中的web_socket_channel依赖升级到最新稳定版,修复已知的版本兼容问题。抓包定位问题
可使用抓包工具抓取模拟器的请求日志,确认WebSocket连接是在DNS解析、TCP连接还是TLS握手阶段中断,进一步定位具体原因。
内容的提问来源于stack exchange,提问作者anjo jy
相关产品推荐
相关产品推荐

