From 1d19f727d36e03367ba0863af67675c57a18cf56 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Wed, 29 Apr 2026 14:40:12 +0800 Subject: [PATCH] fix quicClient --- Tun/Punchnet/Actors/SDLContextActor.swift | 57 +++++++++++++---------- Tun/Punchnet/Actors/SDLQuicClient.swift | 2 + 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index cad17c9..9b8ef02 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -268,36 +268,18 @@ actor SDLContextActor { } // 这里必须等待quic的协商完成 - try await Task.sleep(for: .seconds(0.3)) + try await Task.sleep(for: .seconds(0.5)) SDLLogger.log("[SDLContext] start quic client: \(self.config.serverHost)") try await withThrowingTaskGroup { group in - defer { - group.cancelAll() - } - - group.addTask { - for await message in quicClient.messageStream { - await self.handleQUICMessage(message: message) - } - } - - group.addTask { - let timerStream = SDLAsyncTimerStream() - timerStream.start(interval: .seconds(5)) - - for await _ in timerStream.stream { - if Task.isCancelled { - break - } - quicClient.send(type: .ping, data: Data()) - } - SDLLogger.log("[SDLQUICClient] udp pingTask cancel", for: .debug) - } + // 创建一个简单的异步状态等待机制(可以用一个 Actor 或者 AsyncStream 模拟) + let (readyStream, readyContinuation) = AsyncStream.makeStream() group.addTask { for await event in quicClient.eventStream { switch event { + case .ready: + readyContinuation.yield() case .failed(let error): throw error case .cancelled: @@ -308,9 +290,36 @@ actor SDLContextActor { } } + group.addTask { + // 等待信号 + var it = readyStream.makeAsyncIterator() + await it.next() + + try Task.checkCancellation() + + await withThrowingTaskGroup { workerGroup in + workerGroup.addTask { + for await message in quicClient.messageStream { + try Task.checkCancellation() + await self.handleQUICMessage(message: message) + } + } + + workerGroup.addTask { + let timerStream = SDLAsyncTimerStream() + timerStream.start(interval: .seconds(5)) + + for await _ in timerStream.stream { + try Task.checkCancellation() + quicClient.send(type: .ping, data: Data()) + } + SDLLogger.log("[SDLQUICClient] udp pingTask cancel", for: .debug) + } + } + } + try await group.next() } - } private func handleQUICMessage(message: SDLQUICInboundMessage) async { diff --git a/Tun/Punchnet/Actors/SDLQuicClient.swift b/Tun/Punchnet/Actors/SDLQuicClient.swift index 78cc4e8..a942f3c 100644 --- a/Tun/Punchnet/Actors/SDLQuicClient.swift +++ b/Tun/Punchnet/Actors/SDLQuicClient.swift @@ -22,6 +22,7 @@ enum SDLQUICError: Error { } enum SDLQUICEvent: Error { + case ready case failed(Error) case cancelled case writeFailed(Error) @@ -71,6 +72,7 @@ final class SDLQUICClient { switch state { case .ready: self?.startReadTask() + self?.eventCont.yield(.ready) case .failed(let error): self?.eventCont.yield(.failed(error)) case .cancelled: