diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index 7b1b1e7..5163939 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -258,76 +258,94 @@ actor SDLContextActor { private func startQUICClient() async throws { SDLLogger.log("[SDLContext] try start quicClient", for: .debug) - + self.quicWorker?.cancel() await self.quicClient?.stop() - + // 启动monitor let quicClient = SDLQUICClient(host: self.config.serverHost, port: 443) self.quicClient = quicClient - + await quicClient.start() - - try await quicClient.waitReady(timeout: .seconds(3)) - // 这里必须等待quic的协商完成 - try await Task.sleep(for: .seconds(0.3)) - SDLLogger.log("[SDLContext] start quic client: \(self.config.serverHost)") - - try await withTaskCancellationHandler{ - try await withThrowingTaskGroup { group in - defer { - group.cancelAll() - } - - group.addTask { - for await message in await quicClient.messageStream { + + do { + try await quicClient.waitReady(timeout: .seconds(3)) + // 这里必须等待quic的协商完成 + try await Task.sleep(for: .seconds(0.3)) + SDLLogger.log("[SDLContext] start quic client: \(self.config.serverHost)") + + try await withTaskCancellationHandler { + try await withThrowingTaskGroup { group in + defer { + group.cancelAll() + } + + group.addTask { + for await message in await quicClient.messageStream { + if Task.isCancelled { + return + } + await self.handleQUICMessage(message: message) + } if Task.isCancelled { return } - await self.handleQUICMessage(message: message) + throw SDLQUICClientExit.transportClosed("messageStream finished") } - throw SDLQUICClientExit.transportClosed("messageStream finished") - } - - group.addTask { - let exit = await quicClient.run() - - switch exit { - case .normal: - return - case .cancelled: - if Task.isCancelled { + + group.addTask { + let exit = await quicClient.run() + + switch exit { + case .normal: return - } - throw exit - case .transportClosed, .readFailed, .writeFailed: - throw exit - } - } - - group.addTask { - for await event in await quicClient.eventStream { - switch event { - case .failed(let error): - throw error case .cancelled: - throw SDLQUICClientExit.cancelled - case .writeFailed(let error): - throw error + if Task.isCancelled { + return + } + throw exit + case .transportClosed, .readFailed, .writeFailed: + throw exit } } + + group.addTask { + for await event in await quicClient.eventStream { + switch event { + case .failed(let error): + throw error + case .cancelled: + throw SDLQUICClientExit.cancelled + case .writeFailed(let error): + throw error + } + } + if Task.isCancelled { + return + } + throw SDLQUICClientExit.transportClosed("eventStream finished") + } + + do { + let _ = try await group.next() + await quicClient.stop() + } catch { + await quicClient.stop() + throw error + } + } + + } onCancel: { + Task { + await quicClient.stop() } - - let _ = try await group.next() - } - - } onCancel: { - Task { - await quicClient.stop() } + } catch { + await quicClient.stop() + throw error } } - + private func handleQUICMessage(message: SDLQUICInboundMessage) async { switch message { case .welcome(let welcome): diff --git a/Tun/Punchnet/Actors/SDLQuicClient.swift b/Tun/Punchnet/Actors/SDLQuicClient.swift index 0d44d2d..6f90313 100644 --- a/Tun/Punchnet/Actors/SDLQuicClient.swift +++ b/Tun/Punchnet/Actors/SDLQuicClient.swift @@ -136,27 +136,20 @@ actor SDLQUICClient { } func run() async -> SDLQUICClientExit { - await withTaskCancellationHandler { - await withTaskGroup(of: SDLQUICClientExit.self) { group in - group.addTask { - await self.readLoop() - } - - group.addTask { - await self.heartbeatLoop() - } - - let exit = await group.next() ?? .normal - group.cancelAll() - await self.stop() - self.finishStreams() - - return exit + await withTaskGroup(of: SDLQUICClientExit.self) { group in + group.addTask { + await self.readLoop() } - } onCancel: { - Task { - await self.stop() + + group.addTask { + await self.heartbeatLoop() } + + let exit = await group.next() ?? .normal + group.cancelAll() + self.finishStreams() + + return exit } }