解决网络状态变化的问题
This commit is contained in:
parent
779947677c
commit
e68bf7e106
@ -86,7 +86,7 @@ actor SDLContextActor {
|
|||||||
nonisolated private let arpServer: ArpServer
|
nonisolated private let arpServer: ArpServer
|
||||||
|
|
||||||
// 网络状态变化的健康
|
// 网络状态变化的健康
|
||||||
private var monitor: SDLNetworkMonitor?
|
private var monitor: SDLPathMonitor?
|
||||||
private var monitorWorker: Task<Void, Never>?
|
private var monitorWorker: Task<Void, Never>?
|
||||||
|
|
||||||
// 内部socket通讯
|
// 内部socket通讯
|
||||||
@ -338,20 +338,25 @@ actor SDLContextActor {
|
|||||||
self.monitorWorker = nil
|
self.monitorWorker = nil
|
||||||
|
|
||||||
// 启动monitor
|
// 启动monitor
|
||||||
let monitor = SDLNetworkMonitor()
|
let monitor = SDLPathMonitor()
|
||||||
monitor.start()
|
monitor.start()
|
||||||
SDLLogger.log("[SDLContext] monitor started")
|
SDLLogger.log("[SDLContext] monitor started")
|
||||||
self.monitor = monitor
|
self.monitor = monitor
|
||||||
|
|
||||||
self.monitorWorker = Task.detached {
|
self.monitorWorker = Task {
|
||||||
for await event in monitor.eventStream {
|
for await status in monitor.statusStream() {
|
||||||
switch event {
|
switch status {
|
||||||
case .changed:
|
case .satisfied:
|
||||||
// 需要重新探测网络的nat类型
|
SDLLogger.log("[Path] stable satisfied", for: .debug)
|
||||||
await self.probeNatType()
|
// await contextActor.networkPathDidBecomeSatisfied(snapshot)
|
||||||
SDLLogger.log("didNetworkPathChanged, nat type is:")
|
case .unsatisfied:
|
||||||
case .unreachable:
|
SDLLogger.log("[Path] stable unsatisfied", for: .debug)
|
||||||
SDLLogger.log("didNetworkPathUnreachable")
|
// await contextActor.networkPathDidBecomeUnsatisfied(snapshot)
|
||||||
|
case .requiresConnection:
|
||||||
|
SDLLogger.log("[Path] stable requiresConnection", for: .debug)
|
||||||
|
|
||||||
|
@unknown default:
|
||||||
|
SDLLogger.log("[Path] stable unknown", for: .debug)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
Tun/Punchnet/NWPath/SDLPathDebounceActor.swift
Normal file
54
Tun/Punchnet/NWPath/SDLPathDebounceActor.swift
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// SDLPathDebounceActor.swift
|
||||||
|
// punchnet
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/4/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Network
|
||||||
|
|
||||||
|
actor SDLPathDebounceActor {
|
||||||
|
private var lastSnapshot: SDLPathSnapshot?
|
||||||
|
private var debounceTask: Task<Void, Never>?
|
||||||
|
|
||||||
|
private let delay: Duration
|
||||||
|
|
||||||
|
public let statusStream: AsyncStream<NWPath.Status>
|
||||||
|
private let statusCont: AsyncStream<NWPath.Status>.Continuation
|
||||||
|
|
||||||
|
init(delay: Duration = .seconds(2)) {
|
||||||
|
self.delay = delay
|
||||||
|
let (stream, cont) = AsyncStream.makeStream(of: NWPath.Status.self)
|
||||||
|
self.statusStream = stream
|
||||||
|
self.statusCont = cont
|
||||||
|
}
|
||||||
|
|
||||||
|
func submit(_ snapshot: SDLPathSnapshot) {
|
||||||
|
guard snapshot != lastSnapshot else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lastSnapshot = snapshot
|
||||||
|
|
||||||
|
self.debounceTask?.cancel()
|
||||||
|
self.debounceTask = Task { [delay] in
|
||||||
|
try? await Task.sleep(for: delay)
|
||||||
|
|
||||||
|
guard !Task.isCancelled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await self.handleStableSnapshot(snapshot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleStableSnapshot(_ snapshot: SDLPathSnapshot) async {
|
||||||
|
self.statusCont.yield(snapshot.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
debounceTask?.cancel()
|
||||||
|
debounceTask = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
38
Tun/Punchnet/NWPath/SDLPathMonitor.swift
Normal file
38
Tun/Punchnet/NWPath/SDLPathMonitor.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// SDLPathMonitor.swift
|
||||||
|
// punchnet
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/4/29.
|
||||||
|
//
|
||||||
|
import Foundation
|
||||||
|
import Network
|
||||||
|
|
||||||
|
final class SDLPathMonitor {
|
||||||
|
private let monitor = NWPathMonitor()
|
||||||
|
private let queue = DispatchQueue(label: "com.sdlan.path-monitor")
|
||||||
|
private let debouncer = SDLPathDebounceActor(delay: .seconds(2))
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
monitor.pathUpdateHandler = { path in
|
||||||
|
let snapshot = SDLPathSnapshot(path)
|
||||||
|
|
||||||
|
Task {
|
||||||
|
await self.debouncer.submit(snapshot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.start(queue: queue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func statusStream() -> AsyncStream<NWPath.Status> {
|
||||||
|
return self.debouncer.statusStream
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
Task {
|
||||||
|
await debouncer.stop()
|
||||||
|
}
|
||||||
|
monitor.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
32
Tun/Punchnet/NWPath/SDLPathSnapshot.swift
Normal file
32
Tun/Punchnet/NWPath/SDLPathSnapshot.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// PathSnapshot.swift
|
||||||
|
// punchnet
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2026/4/29.
|
||||||
|
//
|
||||||
|
import Foundation
|
||||||
|
import Network
|
||||||
|
|
||||||
|
struct SDLPathSnapshot: Equatable, Sendable {
|
||||||
|
let status: NWPath.Status
|
||||||
|
let isExpensive: Bool
|
||||||
|
let isConstrained: Bool
|
||||||
|
let supportsIPv4: Bool
|
||||||
|
let supportsIPv6: Bool
|
||||||
|
let supportsDNS: Bool
|
||||||
|
let usesWiFi: Bool
|
||||||
|
let usesWired: Bool
|
||||||
|
let usesCellular: Bool
|
||||||
|
|
||||||
|
init(_ path: NWPath) {
|
||||||
|
self.status = path.status
|
||||||
|
self.isExpensive = path.isExpensive
|
||||||
|
self.isConstrained = path.isConstrained
|
||||||
|
self.supportsIPv4 = path.supportsIPv4
|
||||||
|
self.supportsIPv6 = path.supportsIPv6
|
||||||
|
self.supportsDNS = path.supportsDNS
|
||||||
|
self.usesWiFi = path.usesInterfaceType(.wifi)
|
||||||
|
self.usesWired = path.usesInterfaceType(.wiredEthernet)
|
||||||
|
self.usesCellular = path.usesInterfaceType(.cellular)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user