Flutter中Socket关闭后HTTP及全局网络异常问题求助
问题分析与解决思路
从你提供的代码和报错信息来看,核心问题是Socket资源未彻底释放+网络切换后应用未同步更新网络状态,导致全局网络连接失效。以下是针对性的解决方案:
1. 彻底清理Socket相关资源
当前代码只关闭了Socket,但未取消监听的StreamSubscription(_sockStrem),这会导致资源泄漏,占用网络接口。修改sockListenCb方法:
void sockListenCb(event) async { String data = String.fromCharCodes(event); print(data); print('----------->>>>'); // 1. 先取消Socket流的订阅,避免资源泄漏 if (_sockStrem != null) { await _sockStrem?.cancel(); _sockStrem = null; } // 2. 完整关闭Socket:先flush确保数据发送完成,再close if (_socket != null) { try { await _socket?.flush(); await _socket?.close(); await Future.delayed(const Duration(milliseconds: 100)); _socket = null; print('回调销毁socket =>$_socket'); } catch (e) { print('销毁socket出错: $e'); _socket?.destroy(); _socket = null; } } await FlutterIotWifi.disconnect(); // 3. 等待网络切换完成后再进行后续操作 await _waitForNetworkStable(); } // 新增:等待网络连接稳定的方法 Future<void> _waitForNetworkStable() async { // 循环检查网络状态,直到能正常访问目标服务器 for (int i = 0; i < 10; i++) { await Future.delayed(const Duration(seconds: 1)); try { // 验证是否能解析目标域名(替代ping) final addr = await InternetAddress.lookup('qdevice.duoqin.com'); if (addr.isNotEmpty && addr[0].rawAddress.isNotEmpty) { return; } } catch (_) {} } }
同时,在Socket错误处理中也要同步清理资源:
void errorHandler(error) { print('Socket监听错误: $error'); _sockStrem?.cancel(); _sockStrem = null; _socket?.close(); _socket = null; }
2. 避免复用全局HTTP客户端
全局http.Client会缓存旧的网络连接,网络切换后需要重新创建实例,不要复用:
// 每次HTTP请求都创建新的Client,用完即关闭 Future<void> sendHttpRequest() async { final client = http.Client(); try { final response = await client.get( Uri.parse('https://qdevice.duoqin.com/device/action?culture=en-US') ); // 处理响应逻辑 } catch (e) { print('HTTP请求失败: $e'); } finally { client.close(); } }
3. 修正WiFi连接判断逻辑
当前用Future.delayed(8秒)判断连接状态非常不可靠,改用WiFi状态监听:
void _connectWifi(String ssid, String password, Function(bool) callback) async { if (!await WiFiForIoTPlugin.isEnabled()) { await WiFiForIoTPlugin.setEnabled(true); } // 监听WiFi连接状态变化 final subscription = WiFiForIoTPlugin.onWiFiConnectionChanged().listen((event) async { if (event.isConnected && event.ssid == ssid) { await subscription.cancel(); callback(true); } }); // 发起连接 await FlutterIotWifi.connect(ssid, password, prefix: false); // 设置超时:10秒内未连接上则返回失败 await Future.delayed(const Duration(seconds: 10), () async { if (!subscription.isPaused) { await subscription.cancel(); callback(false); } }); }
4. 监听系统网络切换事件
用connectivity_plus监听网络状态变化,在切换到正常WiFi后重置网络相关资源:
// 在initState中添加监听 @override void initState() { super.initState(); Connectivity().onConnectivityChanged.listen((result) { if (result == ConnectivityResult.wifi) { // 网络切换到WiFi,可在此重置HTTP客户端或清理旧连接 _socket = null; _sockStrem = null; } }); }
内容的提问来源于stack exchange,提问作者李大龙
相关产品推荐
相关产品推荐

