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

Dart/Flutter iOS端KeepAlive Socket连接断连无法检测问题咨询

问题核心原因

  • 你的代码中定义了RawSocketOption但没有传入Socket.connect方法,配置完全未生效
  • iOS系统默认TCP KeepAlive探测策略的时间阈值极高(默认2小时才启动探测),仅开启SO_KEEPALIVE开关无法及时触发断连回调
  • 静默断网场景下(如直接关闭WiFi),TCP连接没有双向数据交互,系统无法及时感知连接失效

修复方案

1. 修正KeepAlive配置传入逻辑,补全全平台探测参数

不仅要开启SO_KEEPALIVE,还要显式配置探测间隔、重试次数、重试间隔三个核心参数,确保系统能在秒级感知断连:

Future<bool> tryConnectSocket() async {
  String ip = "192.168.9.101"; 
  int port = 35000;
  // 统一配置KeepAlive参数:首次探测空闲等待10s,每次探测间隔2s,重试3次失败即判定断连
  const keepAliveIdle = 10;
  const keepAliveInterval = 2;
  const keepAliveCount = 3;

  try {
    List<RawSocketOption> socketOptions = [];
    if (Platform.isAndroid) {
      socketOptions.add(RawSocketOption.fromBool(0x1, 0x0009, true));
      // 安卓补全TCP KeepAlive参数
      socketOptions.add(RawSocketOption.fromInt(6 /* IPPROTO_TCP */, 0x4 /* TCP_KEEPIDLE */, keepAliveIdle));
      socketOptions.add(RawSocketOption.fromInt(6, 0x5 /* TCP_KEEPINTVL */, keepAliveInterval));
      socketOptions.add(RawSocketOption.fromInt(6, 0x6 /* TCP_KEEPCNT */, keepAliveCount));
    } else if (Platform.isIOS) {
      socketOptions.add(RawSocketOption.fromBool(0xffff /* SOL_SOCKET */, 0x0008 /* SO_KEEPALIVE */, true));
      // iOS补全TCP KeepAlive参数
      socketOptions.add(RawSocketOption.fromInt(6 /* IPPROTO_TCP */, 0x10 /* TCP_KEEPALIVE */, keepAliveIdle));
      socketOptions.add(RawSocketOption.fromInt(6, 0x102 /* TCP_KEEPCNT */, keepAliveCount));
      socketOptions.add(RawSocketOption.fromInt(6, 0x101 /* TCP_KEEPINTVL */, keepAliveInterval));
    }

    Socket s = await Socket.connect(
      ip, 
      port, 
      timeout: const Duration(seconds: 10),
      // 传入配置的Socket参数
      socketOptions: socketOptions
    ).timeout(const Duration(seconds: 10),
        onTimeout: () {
          log("ERROR ON SOCKET TIMEOUT");
          return Socket.connect(ip, port, socketOptions: socketOptions);
        }).catchError((e) {
      log("ERROR ON SOCKET $e");
      return Socket.connect(ip, port, socketOptions: socketOptions);
    }).onError((error, stackTrace) {
      log("ERROR ON SOCKET $error");
      return Socket.connect(ip, port, socketOptions: socketOptions);
    });
    
    s.listen((msg) {}, cancelOnError: false, onError: (e) {
      log("ERROR ON SOCKET $e");
    }, onDone: () {
      log("Socket DONE");
    });
    log("DONE");
    return true;
  } catch (e) {
    log("ERROR ON LISTENING TO SOCKET $e");
    return false;
  }
}

2. 新增应用层心跳机制(兼容性最佳)

系统层KeepAlive受不同厂商、系统版本的策略限制,最稳妥的方案是在应用层实现心跳逻辑:

  • 每隔固定时间(如5s)向服务端发送一个极小的心跳数据包
  • 若连续3次未收到服务端的心跳响应,主动关闭当前Socket,触发onDone回调
  • 该方案在iOS、Android端表现完全一致,不受系统策略影响

3. 配合网络状态监听辅助判断

接入网络状态监听工具,当系统检测到网络断开、切换时,主动校验当前Socket的可用性,若失效则主动销毁重建。


内容的提问来源于stack exchange,提问作者Mahmood Bkh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:24:05