diff --git a/Sources/Nats/NatsConnection.swift b/Sources/Nats/NatsConnection.swift index aea7752..f66f01d 100644 --- a/Sources/Nats/NatsConnection.swift +++ b/Sources/Nats/NatsConnection.swift @@ -305,12 +305,31 @@ class ConnectionHandler: ChannelInboundHandler { } do { - try await connectToServer(s: s) + // ⭐️ 单节点连接超时保护:8秒内连不上就跳过该节点 + // 防止 iOS 网络不可达时 TCP 超时堆积(默认30-75秒/节点) + try await withThrowingTaskGroup(of: Void.self) { group in + group.addTask { + try await self.connectToServer(s: s) + } + group.addTask { + try await Task.sleep(nanoseconds: 8_000_000_000) + throw NatsError.ConnectError.timeout + } + do { + try await group.next()! + } catch { + group.cancelAll() + throw error + } + group.cancelAll() + } + } catch is CancellationError { + throw CancellationError() } catch let error as NatsError.ConnectError { if case .invalidConfig(_) = error { throw error } - logger.debug("error connecting to server: \(error)") + logger.debug("error connecting to server (8s timeout): \(error)") lastErr = error continue } catch { @@ -847,7 +866,9 @@ class ConnectionHandler: ChannelInboundHandler { internal func sendPing(_ rttCommand: RttCommand? = nil) async { let pingsOut = self.outstandingPings.wrappingIncrementThenLoad( ordering: AtomicUpdateOrdering.relaxed) - if pingsOut > 2 { + if pingsOut > 1 { + // ⭐️ 从 > 2 改为 > 1:缩短断连检测窗口 + // 原杣2次ping无响应(~20秒)即判定断连,加快用户感知 handleDisconnect() return }