优化superClient的回调模型

This commit is contained in:
anlicheng 2026-01-08 11:53:00 +08:00
parent aa26d65869
commit f6288ee07d
3 changed files with 29 additions and 15 deletions

View File

@ -61,7 +61,7 @@ actor SDLPuncherActor {
private func tryHole(request: RegisterRequest) async {
var queryInfo = SDLQueryInfo()
queryInfo.dstMac = request.dstMac
guard let message = try? await self.superClientActor?.request(type: .queryInfo, data: try queryInfo.serializedData()).get() else {
guard let message = try? await self.superClientActor?.request(type: .queryInfo, data: try queryInfo.serializedData()) else {
return
}

View File

@ -17,7 +17,7 @@ actor SDLSuperClientActor {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
private let asyncChannel: NIOAsyncChannel<ByteBuffer,ByteBuffer>
private let (writeStream, writeContinuation) = AsyncStream.makeStream(of: TcpMessage.self, bufferingPolicy: .unbounded)
private var callbackPromises: [UInt32:EventLoopPromise<SDLSuperInboundMessage>] = [:]
private var continuations: [UInt32:CheckedContinuation<SDLSuperInboundMessage, Error>] = [:]
public let eventFlow: AsyncStream<SuperEvent>
private let inboundContinuation: AsyncStream<SuperEvent>.Continuation
@ -34,6 +34,12 @@ actor SDLSuperClientActor {
case command(UInt32, SDLCommand)
}
enum SDLSuperClientError: Error {
case timeout
case connectionClosed
case cancelled
}
init(host: String, port: Int, logger: SDLLogger) async throws {
self.logger = logger
@ -139,14 +145,17 @@ actor SDLSuperClientActor {
self.send(type: .ping, packetId: 0, data: Data())
}
func request(type: SDLPacketType, data: Data) -> EventLoopFuture<SDLSuperInboundMessage> {
func request(type: SDLPacketType, data: Data, timeout: Duration = .seconds(5)) async throws -> SDLSuperInboundMessage {
let packetId = idGenerator.nextId()
let promise = self.asyncChannel.channel.eventLoop.makePromise(of: SDLSuperInboundMessage.self)
self.callbackPromises[packetId] = promise
self.writeContinuation.yield(TcpMessage(packetId: packetId, type: type, data: data))
return promise.futureResult
return try await withCheckedThrowingContinuation { cont in
self.continuations[packetId] = cont
self.writeContinuation.yield(TcpMessage(packetId: packetId, type: type, data: data))
Task {
try? await Task.sleep(for: timeout)
self.timeout(packetId: packetId)
}
}
}
func send(type: SDLPacketType, packetId: UInt32, data: Data) {
@ -155,12 +164,17 @@ actor SDLSuperClientActor {
//
private func fireCallback(message: SDLSuperInboundMessage) {
if let promise = self.callbackPromises[message.msgId] {
self.asyncChannel.channel.eventLoop.execute {
promise.succeed(message)
}
self.callbackPromises.removeValue(forKey: message.msgId)
guard let cont = self.continuations.removeValue(forKey: message.msgId) else {
return
}
cont.resume(returning: message)
}
private func timeout(packetId: UInt32) {
guard let cont = self.continuations.removeValue(forKey: packetId) else {
return
}
cont.resume(throwing: SDLSuperClientError.timeout)
}
deinit {

View File

@ -298,7 +298,7 @@ public class SDLContext {
registerSuper.token = self.config.token
registerSuper.networkCode = self.config.networkCode
registerSuper.hostname = self.config.hostname
guard let message = try await self.superClientActor?.request(type: .registerSuper, data: try registerSuper.serializedData()).get() else {
guard let message = try await self.superClientActor?.request(type: .registerSuper, data: try registerSuper.serializedData()) else {
return
}