fix SuperClient
This commit is contained in:
parent
a648fb2204
commit
b984f7e4e9
@ -8,20 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Network
|
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 {
|
actor SDLSuperClient {
|
||||||
enum State {
|
enum State {
|
||||||
case idle
|
case idle
|
||||||
@ -33,30 +19,24 @@ actor SDLSuperClient {
|
|||||||
|
|
||||||
private let frameParser: SDLSuperFrameParser
|
private let frameParser: SDLSuperFrameParser
|
||||||
|
|
||||||
|
private let queue = DispatchQueue(label: "com.sdl.SuperClient.queue") // 专用队列保证线程安全
|
||||||
|
|
||||||
// 数据流
|
// 数据流
|
||||||
public var messageStream: AsyncThrowingStream<SDLQUICInboundMessage, Error>
|
public let messageStream: AsyncThrowingStream<SDLQUICInboundMessage, Error>
|
||||||
private let messageCont: AsyncThrowingStream<SDLQUICInboundMessage, Error>.Continuation
|
private let messageCont: AsyncThrowingStream<SDLQUICInboundMessage, Error>.Continuation
|
||||||
private var isMessageContinuationFinished: Bool = false
|
private var isMessageContinuationFinished: Bool = false
|
||||||
|
|
||||||
private var readTask: Task<Void, Never>?
|
private var readTask: Task<Void, Never>?
|
||||||
|
|
||||||
private var connection: NWConnection?
|
|
||||||
|
|
||||||
private let serverEndpoint: SDLConfiguration.ResolvedServerEndpoint
|
private let connection: NWConnection
|
||||||
private let port: UInt16
|
|
||||||
|
|
||||||
init(serverEndpoint: SDLConfiguration.ResolvedServerEndpoint, port: UInt16, maxBufferSize: Int = 2 * 1024 * 1024) {
|
init(serverEndpoint: SDLConfiguration.ResolvedServerEndpoint, port: UInt16, maxBufferSize: Int = 2 * 1024 * 1024) {
|
||||||
self.serverEndpoint = serverEndpoint
|
|
||||||
self.port = port
|
|
||||||
|
|
||||||
self.frameParser = SDLSuperFrameParser(maxBufferSize: maxBufferSize)
|
self.frameParser = SDLSuperFrameParser(maxBufferSize: maxBufferSize)
|
||||||
(self.messageStream, self.messageCont) = AsyncThrowingStream.makeStream(of: SDLQUICInboundMessage.self)
|
|
||||||
}
|
let pairs = AsyncThrowingStream.makeStream(of: SDLQUICInboundMessage.self)
|
||||||
|
self.messageStream = pairs.stream
|
||||||
func start() {
|
self.messageCont = pairs.continuation
|
||||||
let serverEndpoint = self.serverEndpoint
|
|
||||||
let queue = DispatchQueue(label: "com.sdl.SuperClient.queue") // 专用队列保证线程安全
|
|
||||||
|
|
||||||
let options = NWProtocolTLS.Options()
|
let options = NWProtocolTLS.Options()
|
||||||
serverEndpoint.host.withCString {
|
serverEndpoint.host.withCString {
|
||||||
sec_protocol_options_set_tls_server_name(options.securityProtocolOptions, $0)
|
sec_protocol_options_set_tls_server_name(options.securityProtocolOptions, $0)
|
||||||
@ -81,17 +61,17 @@ actor SDLSuperClient {
|
|||||||
// 关键:让 Network.framework 忽略系统代理
|
// 关键:让 Network.framework 忽略系统代理
|
||||||
params.preferNoProxies = true
|
params.preferNoProxies = true
|
||||||
|
|
||||||
let connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params)
|
self.connection = NWConnection(host: Self.makeEndpointHost(address: serverEndpoint.ip), port: .init(rawValue: port)!, using: params)
|
||||||
|
}
|
||||||
connection.stateUpdateHandler = { [weak self] state in
|
|
||||||
|
func start() {
|
||||||
|
self.connection.stateUpdateHandler = { [weak self] state in
|
||||||
SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug)
|
SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug)
|
||||||
Task {
|
Task {
|
||||||
await self?.handleConnectionState(state: state)
|
await self?.handleConnectionState(state: state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connection.start(queue: queue)
|
self.connection.start(queue: queue)
|
||||||
|
|
||||||
self.connection = connection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func makeEndpointHost(address ip: String) -> NWEndpoint.Host {
|
private static func makeEndpointHost(address ip: String) -> NWEndpoint.Host {
|
||||||
@ -135,11 +115,12 @@ actor SDLSuperClient {
|
|||||||
|
|
||||||
private func startReadTask() {
|
private func startReadTask() {
|
||||||
self.readTask?.cancel()
|
self.readTask?.cancel()
|
||||||
|
|
||||||
self.readTask = Task {
|
self.readTask = Task {
|
||||||
do {
|
do {
|
||||||
while true {
|
while true {
|
||||||
try Task.checkCancellation()
|
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)
|
let frames = try self.frameParser.parseFrames(data: data)
|
||||||
for frame in frames {
|
for frame in frames {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
@ -157,7 +138,7 @@ actor SDLSuperClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func send(type: SDLPacketType, data: Data) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,11 +157,7 @@ actor SDLSuperClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func readOnce() async throws -> Data {
|
private static func readOnce(connection: NWConnection) async throws -> Data {
|
||||||
guard let connection = self.connection else {
|
|
||||||
throw SDLSuperError.connectionCancelled
|
|
||||||
}
|
|
||||||
|
|
||||||
let readContinuation = OnceContinuation<Data, Error>()
|
let readContinuation = OnceContinuation<Data, Error>()
|
||||||
|
|
||||||
return try await withTaskCancellationHandler {
|
return try await withTaskCancellationHandler {
|
||||||
@ -215,9 +192,8 @@ actor SDLSuperClient {
|
|||||||
self.readTask = nil
|
self.readTask = nil
|
||||||
|
|
||||||
let connection = self.connection
|
let connection = self.connection
|
||||||
self.connection = nil
|
connection.stateUpdateHandler = nil
|
||||||
connection?.stateUpdateHandler = nil
|
connection.cancel()
|
||||||
connection?.cancel()
|
|
||||||
|
|
||||||
self.finishMessageContinuationIfNeed(throwing: nil)
|
self.finishMessageContinuationIfNeed(throwing: nil)
|
||||||
|
|
||||||
|
|||||||
20
Tun/Super/SDLSuperError.swift
Normal file
20
Tun/Super/SDLSuperError.swift
Normal file
@ -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
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user