From 2618ac3d050c21fcda1fdee07d599e1f6fd4b8fa Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Wed, 27 May 2026 20:16:26 +0800 Subject: [PATCH] fix superClient --- Tun/Super/SDLSuperClient.swift | 61 +++++++++++++--------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/Tun/Super/SDLSuperClient.swift b/Tun/Super/SDLSuperClient.swift index f4b53f2..c294b0b 100644 --- a/Tun/Super/SDLSuperClient.swift +++ b/Tun/Super/SDLSuperClient.swift @@ -61,43 +61,18 @@ final class SDLSuperClient: @unchecked Sendable { guard self.markStarted() else { return } - + + let stateStream = self.makeStateStream() defer { self.stop() } - let stateStream = Self.makeStateStream(for: self.connection) - let promise = AsyncPromise() - self.connection.start(queue: self.queue) - try await withTaskCancellationHandler { - try await withThrowingTaskGroup { group in - group.addTask { - do { - for try await state in stateStream { - switch state { - case .ready: - await promise.succeed(true) - default: - () - } - } - } catch let err { - await promise.fail(err) - throw err - } - } - - group.addTask { - _ = try await promise.value() - try Task.checkCancellation() - try await self.readLoop() - } - - try await group.next() - } + self.connection.start(queue: self.queue) + try await self.waitUntilReady(stateStream) + try await self.readLoop() } onCancel: { - self.stop() + self.connection.cancel() } } @@ -113,24 +88,36 @@ final class SDLSuperClient: @unchecked Sendable { preconditionFailure("invalid super server IP: \(ip)") } - private static func makeStateStream(for connection: NWConnection) -> AsyncThrowingStream { + private func makeStateStream() -> AsyncThrowingStream { + let connection = self.connection return AsyncThrowingStream(bufferingPolicy: .bufferingNewest(16)) { continuation in - connection.stateUpdateHandler = { state in + connection.stateUpdateHandler = { [weak self] state in SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug) switch state { case .failed(let error): - continuation.finish(throwing: error) + let wrappedError = SDLSuperError.connectionFailed(error) + self?.finishMessageStream(throwing: wrappedError) + continuation.finish(throwing: wrappedError) case .cancelled: + self?.finishMessageStream(throwing: SDLSuperError.connectionCancelled) continuation.finish(throwing: SDLSuperError.connectionCancelled) default: continuation.yield(state) } } - - continuation.onTermination = { _ in - connection.stateUpdateHandler = nil + } + } + + private func waitUntilReady(_ stateStream: AsyncThrowingStream) async throws { + for try await state in stateStream { + try Task.checkCancellation() + + if case .ready = state { + return } } + + throw SDLSuperError.connectionCancelled } private func readLoop() async throws {