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

Flutter调试时WebSocket相关报错含义解析求助

问题描述

我的应用通过WebSocket接收作为热点的ESP32发送的信息,通过接口处理数据后用GetX存储和处理。调试时应用会暂停,继续运行后出现大量报错,但90%的功能仍能正常使用。

报错栈信息

E/flutter (17169): #32     _StreamController._add (dart:async/stream_controller.dart:658:7)
E/flutter (17169): #33     _StreamController.add (dart:async/stream_controller.dart:606:5)
E/flutter (17169): #34     _Socket._onData (dart:io-patch/socket_patch.dart:2447:41)
E/flutter (17169): #35     _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (17169): #36     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (17169): #37     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (17169): #38     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:784:19)
E/flutter (17169): #39     _StreamController._add (dart:async/stream_controller.dart:658:7)
E/flutter (17169): #40     _StreamController.add (dart:async/stream_controller.dart:606:5)
E/flutter (17169): #41     new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1936:33)
E/flutter (17169): #42     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1379:14)
E/flutter (17169): #43     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (17169): #44     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
E/flutter (17169): 

补充调试信息

调试器中途会停止,并输出以下5条重复错误:

Main isolate is paused in the debugger

****
Error._throw (dart:core-patch/errors_patch.dart:27)
Error.throwWithStackTrace (c:\src\flutter\bin\cache\pkg\sky_engine\lib\core\errors.dart:120)
_rootHandleError.<anonymous closure> (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\zone.dart:1386)
_microtaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:40)
_startMicrotaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:49)
***
Error._throw (dart:core-patch/errors_patch.dart:27)
Error.throwWithStackTrace (c:\src\flutter\bin\cache\pkg\sky_engine\lib\core\errors.dart:120)
_rootHandleError.<anonymous closure> (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\zone.dart:1386)
_microtaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:40)
_startMicrotaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:49)
***
Error._throw (dart:core-patch/errors_patch.dart:27)
Error.throwWithStackTrace (c:\src\flutter\bin\cache\pkg\sky_engine\lib\core\errors.dart:120)
_rootHandleError.<anonymous closure> (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\zone.dart:1386)
_microtaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:40)
_startMicrotaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:49)
***
Error._throw (dart:core-patch/errors_patch.dart:27)
Error.throwWithStackTrace (c:\src\flutter\bin\cache\pkg\sky_engine\lib\core\errors.dart:120)
_rootHandleError.<anonymous closure> (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\zone.dart:1386)
_microtaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:40)
_startMicrotaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:49)
***
Error._throw (dart:core-patch/errors_patch.dart:27)
Error.throwWithStackTrace (c:\src\flutter\bin\cache\pkg\sky_engine\lib\core\errors.dart:120)
_rootHandleError.<anonymous closure> (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\zone.dart:1386)
_microtaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:40)
_startMicrotaskLoop (c:\src\flutter\bin\cache\pkg\sky_engine\lib\async\schedule_microtask.dart:49)

排查与解决方法

  1. 捕获WebSocket消息处理异常
    从报错栈看,问题出在Socket数据接收后的StreamController操作,大概率是消息解析或GetX状态更新时未捕获异常,导致错误流入微任务队列无法处理。在WebSocket监听回调里加try-catch覆盖所有逻辑:

    webSocket.listen(
      (message) {
        try {
          // 原有的数据解析、GetX状态更新代码
        } catch (e, stackTrace) {
          print('处理WebSocket消息出错: $e\n$stackTrace');
          // 可添加日志记录或降级处理逻辑
        }
      },
      onError: (error) => print('WebSocket连接错误: $error'),
      onDone: () => print('WebSocket连接已关闭'),
    );
    
  2. 确保GetX状态更新在主线程
    WebSocket的回调运行在IO线程,直接更新GetX状态可能引发线程冲突。用WidgetsBinding把状态更新逻辑抛到主线程执行:

    WidgetsBinding.instance.addPostFrameCallback((_) {
      // GetX状态更新操作,例如:
      Get.find<YourDataController>().updateData(parsedMessage);
    });
    
  3. 处理调试暂停导致的消息堆积
    调试暂停期间,ESP32可能持续发消息导致WebSocket缓存溢出。可以临时降低ESP32的消息发送频率,或者在应用里加简单节流:

    DateTime _lastProcessTime = DateTime.now();
    void handleMessage(dynamic message) {
      if (DateTime.now().difference(_lastProcessTime).inMilliseconds > 500) {
        _lastProcessTime = DateTime.now();
        // 执行消息处理逻辑
      }
    }
    
  4. 优化WebSocket连接稳定性
    ESP32作为热点可能存在网络波动,未处理的断开重连会引发错误。添加自动重连机制,并在重连时取消旧订阅:

    WebSocket? _currentWs;
    StreamSubscription? _wsSubscription;
    
    void _connectWs() async {
      try {
        _currentWs = await WebSocket.connect('ws://你的ESP32IP地址');
        _wsSubscription?.cancel();
        _wsSubscription = _currentWs?.listen(handleMessage);
      } catch (e) {
        print('连接失败,3秒后重试');
        Future.delayed(const Duration(seconds: 3), _connectWs);
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:24:52