From b984f7e4e9682f9a85834b21049760492fdf3048 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 22 May 2026 15:34:42 +0800 Subject: [PATCH] fix SuperClient --- Tun/Super/SDLSuperClient.swift | 66 +++++++++++----------------------- Tun/Super/SDLSuperError.swift | 20 +++++++++++ 2 files changed, 41 insertions(+), 45 deletions(-) create mode 100644 Tun/Super/SDLSuperError.swift diff --git a/Tun/Super/SDLSuperClient.swift b/Tun/Super/SDLSuperClient.swift index e209dd7..8a88bfb 100644 --- a/Tun/Super/SDLSuperClient.swift +++ b/Tun/Super/SDLSuperClient.swift @@ -8,20 +8,6 @@ import Foundation import Network -// 定义错误类型,便于上层处理 -enum SDLSuperError: Error { - case connectionFailed(Error) - case connectionCancelled - case writeFailed(Error) - - case internalError(Error) - - case timeout - case decodeError(String) - case packetTooLarge - case dataStreamClosed -} - actor SDLSuperClient { enum State { case idle @@ -33,30 +19,24 @@ actor SDLSuperClient { private let frameParser: SDLSuperFrameParser + private let queue = DispatchQueue(label: "com.sdl.SuperClient.queue") // 专用队列保证线程安全 + // 数据流 - public var messageStream: AsyncThrowingStream + public let messageStream: AsyncThrowingStream private let messageCont: AsyncThrowingStream.Continuation private var isMessageContinuationFinished: Bool = false private var readTask: Task? - - private var connection: NWConnection? - private let serverEndpoint: SDLConfiguration.ResolvedServerEndpoint - private let port: UInt16 + private let connection: NWConnection init(serverEndpoint: SDLConfiguration.ResolvedServerEndpoint, port: UInt16, maxBufferSize: Int = 2 * 1024 * 1024) { - self.serverEndpoint = serverEndpoint - self.port = port - self.frameParser = SDLSuperFrameParser(maxBufferSize: maxBufferSize) - (self.messageStream, self.messageCont) = AsyncThrowingStream.makeStream(of: SDLQUICInboundMessage.self) - } - - func start() { - let serverEndpoint = self.serverEndpoint - let queue = DispatchQueue(label: "com.sdl.SuperClient.queue") // 专用队列保证线程安全 - + + let pairs = AsyncThrowingStream.makeStream(of: SDLQUICInboundMessage.self) + self.messageStream = pairs.stream + self.messageCont = pairs.continuation + let options = NWProtocolTLS.Options() serverEndpoint.host.withCString { sec_protocol_options_set_tls_server_name(options.securityProtocolOptions, $0) @@ -81,17 +61,17 @@ actor SDLSuperClient { // 关键:让 Network.framework 忽略系统代理 params.preferNoProxies = true - let connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params) - - connection.stateUpdateHandler = { [weak self] state in + self.connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params) + } + + func start() { + self.connection.stateUpdateHandler = { [weak self] state in SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug) Task { await self?.handleConnectionState(state: state) } } - connection.start(queue: queue) - - self.connection = connection + self.connection.start(queue: queue) } private static func makeEndpointHost(address ip: String) -> NWEndpoint.Host { @@ -135,11 +115,12 @@ actor SDLSuperClient { private func startReadTask() { self.readTask?.cancel() + self.readTask = Task { do { while true { try Task.checkCancellation() - let data = try await self.readOnce() + let data = try await Self.readOnce(connection: self.connection) let frames = try self.frameParser.parseFrames(data: data) for frame in frames { try Task.checkCancellation() @@ -157,7 +138,7 @@ actor SDLSuperClient { } func send(type: SDLPacketType, data: Data) { - guard case .running = state, let connection = self.connection, connection.state == .ready else { + guard case .running = state, connection.state == .ready else { return } @@ -176,11 +157,7 @@ actor SDLSuperClient { }) } - private func readOnce() async throws -> Data { - guard let connection = self.connection else { - throw SDLSuperError.connectionCancelled - } - + private static func readOnce(connection: NWConnection) async throws -> Data { let readContinuation = OnceContinuation() return try await withTaskCancellationHandler { @@ -215,9 +192,8 @@ actor SDLSuperClient { self.readTask = nil let connection = self.connection - self.connection = nil - connection?.stateUpdateHandler = nil - connection?.cancel() + connection.stateUpdateHandler = nil + connection.cancel() self.finishMessageContinuationIfNeed(throwing: nil) diff --git a/Tun/Super/SDLSuperError.swift b/Tun/Super/SDLSuperError.swift new file mode 100644 index 0000000..a6581d8 --- /dev/null +++ b/Tun/Super/SDLSuperError.swift @@ -0,0 +1,20 @@ +// +// SDLSuperError.swift +// punchnet +// +// Created by 安礼成 on 2026/5/22. +// +import Foundation + +// 定义错误类型,便于上层处理 +enum SDLSuperError: Error { + case connectionFailed(Error) + case connectionCancelled + case writeFailed(Error) + + case internalError(Error) + case packetTooLarge + + case decodeError(String) + case dataStreamClosed +}