This commit is contained in:
anlicheng 2026-05-27 21:45:53 +08:00
parent 69815ab701
commit 0e455b187d
6 changed files with 60 additions and 89 deletions

View File

@ -34,6 +34,7 @@ actor SDLSuperService {
do { do {
try await session.run() try await session.run()
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop()
} catch is CancellationError { } catch is CancellationError {
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop() await session.stop()

View File

@ -22,13 +22,7 @@ final class SDLSuperSession: @unchecked Sendable {
} }
func run() async throws { func run() async throws {
do { try await self.runLoops()
try await self.runLoops()
await self.stop()
} catch {
await self.stop()
throw error
}
} }
func stop() async { func stop() async {

View File

@ -43,6 +43,7 @@ actor SDLUDPHoleService {
do { do {
try await session.run() try await session.run()
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop()
} catch is CancellationError { } catch is CancellationError {
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop() await session.stop()

View File

@ -26,12 +26,28 @@ actor SDLUDPHoleSession {
} }
func run() async throws { func run() async throws {
do { let udpHole = try SDLUDPHole()
try await self.runV4() let localAddress = try udpHole.start()
await self.stop() self.udpHole = udpHole
} catch { self.localAddress = localAddress
await self.stop()
throw error SDLLogger.log("[SDLUDPHoleSession] udpHole started, on address: \(localAddress)")
await self.onEvent(.ready(localAddress))
try await withThrowingTaskGroup(of: Void.self) { group in
defer {
group.cancelAll()
}
group.addTask {
try await self.readLoop(udpHole: udpHole)
}
group.addTask {
await self.probeNatType(udpHole: udpHole)
}
try await group.waitForAll()
} }
} }
@ -58,45 +74,10 @@ actor SDLUDPHoleSession {
udpHole.send(type: type, data: data, remoteAddress: remoteAddress) udpHole.send(type: type, data: data, remoteAddress: remoteAddress)
} }
private func runV4() async throws { private func readLoop(udpHole: SDLUDPHole) async throws {
let udpHole = try SDLUDPHole()
let localAddress = try udpHole.start()
self.udpHole = udpHole
self.localAddress = localAddress
SDLLogger.log("[SDLUDPHoleSession] udpHole started, on address: \(localAddress)")
await self.onEvent(.ready(localAddress))
do {
try await withThrowingTaskGroup(of: Void.self) { group in
defer {
group.cancelAll()
}
group.addTask {
try await self.readV4Loop(udpHole: udpHole)
}
group.addTask {
await self.probeNatType(udpHole: udpHole)
}
try await group.waitForAll()
}
} catch {
udpHole.stop()
if self.udpHole === udpHole {
self.udpHole = nil
self.localAddress = nil
}
throw error
}
}
private func readV4Loop(udpHole: SDLUDPHole) async throws {
for try await datagram in udpHole.messageStream { for try await datagram in udpHole.messageStream {
try Task.checkCancellation() try Task.checkCancellation()
try await self.handleV4Message(remoteAddress: datagram.remoteAddress, message: datagram.message) try await self.handleMessage(remoteAddress: datagram.remoteAddress, message: datagram.message)
} }
} }
@ -113,7 +94,7 @@ actor SDLUDPHoleSession {
await self.onEvent(.natType(natType)) await self.onEvent(.natType(natType))
} }
private func handleV4Message(remoteAddress: SocketAddress, message: SDLHoleMessage) async throws { private func handleMessage(remoteAddress: SocketAddress, message: SDLHoleMessage) async throws {
switch message { switch message {
case .control(let control): case .control(let control):
switch control { switch control {

View File

@ -29,6 +29,7 @@ actor SDLUDPHoleV6Service {
do { do {
try await session.run() try await session.run()
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop()
} catch is CancellationError { } catch is CancellationError {
self.clearCurrent(session, generation: generation) self.clearCurrent(session, generation: generation)
await session.stop() await session.stop()

View File

@ -26,46 +26,39 @@ actor SDLUDPHoleV6Session {
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, no local address") SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 started, no local address")
} }
do { try await withThrowingTaskGroup(of: Void.self) { group in
try await withThrowingTaskGroup(of: Void.self) { group in defer {
defer { group.cancelAll()
group.cancelAll()
}
let onEvent = self.onEvent
let onData = self.onData
group.addTask {
for await (remoteAddress, message) in udpHoleV6.messageStream {
try Task.checkCancellation()
switch message {
case .control(let control):
await onEvent(.packet(remoteAddress, control))
case .data(let data):
await onData(data)
}
}
}
group.addTask {
for await event in udpHoleV6.eventStream {
try Task.checkCancellation()
switch event {
case .ready:
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 ready")
case .closed, .errorCaught:
throw SDLContextError.udpHoleClosed
}
}
}
_ = try await group.next()
} }
await self.stop() let onEvent = self.onEvent
} catch { let onData = self.onData
await self.stop()
throw error group.addTask {
for await (remoteAddress, message) in udpHoleV6.messageStream {
try Task.checkCancellation()
switch message {
case .control(let control):
await onEvent(.packet(remoteAddress, control))
case .data(let data):
await onData(data)
}
}
}
group.addTask {
for await event in udpHoleV6.eventStream {
try Task.checkCancellation()
switch event {
case .ready:
SDLLogger.log("[SDLUDPHoleV6Session] udpHoleV6 ready")
case .closed, .errorCaught:
throw SDLContextError.udpHoleClosed
}
}
}
_ = try await group.next()
} }
} }