diff --git a/Tun/Punchnet/Actors/ArpServer.swift b/Tun/Punchnet/Actors/ArpServer.swift index ca99a22..e748a7c 100644 --- a/Tun/Punchnet/Actors/ArpServer.swift +++ b/Tun/Punchnet/Actors/ArpServer.swift @@ -82,7 +82,7 @@ actor ArpServer { var arpRequest = SDLArpRequest() arpRequest.targetIp = targetIp - quicClient.send(type: .arpRequest, data: try arpRequest.serializedData()) + await quicClient.send(type: .arpRequest, data: try arpRequest.serializedData()) } func handleArpResponse(arpResponse: SDLArpResponse) { diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index 9385255..76b4dac 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -166,12 +166,14 @@ actor SDLContextActor { // 启动monitor let quicClient = SDLQUICClient(host: self.config.serverHost, port: 1443) self.quicClient = quicClient - quicClient.start() + await quicClient.start() defer { - self.quicClient?.stop() - self.quicClient = nil - SDLLogger.log("[SDLContext] quicClient: stop") + Task { + await self.quicClient?.stop() + self.quicClient = nil + SDLLogger.log("[SDLContext] quicClient: stop") + } } // 这里必须等待quic的协商完成 @@ -185,7 +187,7 @@ actor SDLContextActor { } group.addTask { - for try await message in quicClient.messageStream { + for try await message in await quicClient.messageStream { try Task.checkCancellation() await self.handleQUICMessage(message: message) } @@ -195,7 +197,7 @@ actor SDLContextActor { while true { try await Task.sleep(for: .seconds(5)) try Task.checkCancellation() - quicClient.send(type: .ping, data: Data()) + await quicClient.send(type: .ping, data: Data()) } SDLLogger.log("[SDLQUICClient] udp pingTask cancel", for: .debug) } @@ -203,7 +205,9 @@ actor SDLContextActor { try await group.next() } } onCancel: { - quicClient.stop() + Task { + await quicClient.stop() + } } } @@ -853,7 +857,7 @@ extension SDLContextActor { if let registerSuperData = try? registerSuper.serializedData() { SDLLogger.log("[SDLContext] will send register super") - self.quicClient?.send(type: .registerSuper, data: registerSuperData) + await self.quicClient?.send(type: .registerSuper, data: registerSuperData) } } diff --git a/Tun/Punchnet/Actors/SDLPuncherActor.swift b/Tun/Punchnet/Actors/SDLPuncherActor.swift index cf1306d..2ba976c 100644 --- a/Tun/Punchnet/Actors/SDLPuncherActor.swift +++ b/Tun/Punchnet/Actors/SDLPuncherActor.swift @@ -90,7 +90,7 @@ actor SDLPuncherActor { phase: .waitingPeerInfo(deadline: now.addingTimeInterval(self.peerInfoTimeout)) ) - quicClient.send(type: .queryInfo, data: queryData) + await quicClient.send(type: .queryInfo, data: queryData) } func handlePeerInfo(using udpHole: SDLUDPHole?, udpHoleV6: SDLUDPHoleV6?, peerInfo: SDLPeerInfo) async { diff --git a/Tun/Punchnet/Actors/SDLQuicClient.swift b/Tun/Punchnet/Actors/SDLQuicClient.swift index fcb0bd7..d6cf263 100644 --- a/Tun/Punchnet/Actors/SDLQuicClient.swift +++ b/Tun/Punchnet/Actors/SDLQuicClient.swift @@ -25,7 +25,7 @@ enum SDLQUICError: Error { case dataStreamClosed } -final class SDLQUICClient { +actor SDLQUICClient { enum State { case idle case running @@ -45,7 +45,6 @@ final class SDLQUICClient { private var connection: NWConnection? private let queue = DispatchQueue(label: "com.sdl.QUICClient.queue") // 专用队列保证线程安全 - private let queueKey = DispatchSpecificKey() private let host: String private let port: UInt16 @@ -56,8 +55,6 @@ final class SDLQUICClient { self.frameParser = SDLQUICFrameParser(maxBufferSize: maxBufferSize) (self.messageStream, self.messageCont) = AsyncThrowingStream.makeStream(of: SDLQUICInboundMessage.self) - - self.queue.setSpecific(key: self.queueKey, value: ()) } func start() { @@ -86,16 +83,8 @@ final class SDLQUICClient { connection.stateUpdateHandler = { [weak self] state in SDLLogger.log("[SDLQUICClient] new state: \(state)", for: .debug) - switch state { - case .ready: - self?.startReadTask() - self?.state = .running - case .failed(let error): - self?.finishMessageContinuationIfNeed(throwing: .connectionFailed(error)) - case .cancelled: - self?.finishMessageContinuationIfNeed(throwing: .connectionCancelled) - default: - () + Task { + await self?.handleConnectionState(state: state) } } connection.start(queue: self.queue) @@ -103,17 +92,21 @@ final class SDLQUICClient { self.connection = connection } - private func finishMessageContinuationIfNeed(throwing error: SDLQUICError?) { - if DispatchQueue.getSpecific(key: queueKey) != nil { - self.finishMessageContinuationIfNeedOnQueue(throwing: error) - } else { - queue.async { [weak self] in - self?.finishMessageContinuationIfNeedOnQueue(throwing: error) - } + private func handleConnectionState(state: NWConnection.State) { + switch state { + case .ready: + self.startReadTask() + self.state = .running + case .failed(let error): + self.finishMessageContinuationIfNeed(throwing: .connectionFailed(error)) + case .cancelled: + self.finishMessageContinuationIfNeed(throwing: .connectionCancelled) + default: + () } } - private func finishMessageContinuationIfNeedOnQueue(throwing error: SDLQUICError?) { + private func finishMessageContinuationIfNeed(throwing error: SDLQUICError?) { guard !self.isMessageContinuationFinished else { return } @@ -160,8 +153,10 @@ final class SDLQUICClient { connection.send(content: packet, completion: .contentProcessed { [weak self] error in if let error { - SDLLogger.log("[SDLQUICClient] send data get error: \(error)", for: .debug) - self?.finishMessageContinuationIfNeed(throwing: .writeFailed(error)) + Task { + SDLLogger.log("[SDLQUICClient] send data get error: \(error)", for: .debug) + await self?.finishMessageContinuationIfNeed(throwing: .writeFailed(error)) + } } }) } @@ -188,16 +183,6 @@ final class SDLQUICClient { } func stop() { - if DispatchQueue.getSpecific(key: queueKey) != nil { - self.stopOnQueue() - } else { - queue.sync { - self.stopOnQueue() - } - } - } - - private func stopOnQueue() { guard self.state != .stopped else { return }