优化superClient的回调模型
This commit is contained in:
parent
aa26d65869
commit
f6288ee07d
@ -61,7 +61,7 @@ actor SDLPuncherActor {
|
|||||||
private func tryHole(request: RegisterRequest) async {
|
private func tryHole(request: RegisterRequest) async {
|
||||||
var queryInfo = SDLQueryInfo()
|
var queryInfo = SDLQueryInfo()
|
||||||
queryInfo.dstMac = request.dstMac
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,8 @@ actor SDLSuperClientActor {
|
|||||||
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
||||||
private let asyncChannel: NIOAsyncChannel<ByteBuffer,ByteBuffer>
|
private let asyncChannel: NIOAsyncChannel<ByteBuffer,ByteBuffer>
|
||||||
private let (writeStream, writeContinuation) = AsyncStream.makeStream(of: TcpMessage.self, bufferingPolicy: .unbounded)
|
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>
|
public let eventFlow: AsyncStream<SuperEvent>
|
||||||
private let inboundContinuation: AsyncStream<SuperEvent>.Continuation
|
private let inboundContinuation: AsyncStream<SuperEvent>.Continuation
|
||||||
|
|
||||||
@ -34,6 +34,12 @@ actor SDLSuperClientActor {
|
|||||||
case command(UInt32, SDLCommand)
|
case command(UInt32, SDLCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SDLSuperClientError: Error {
|
||||||
|
case timeout
|
||||||
|
case connectionClosed
|
||||||
|
case cancelled
|
||||||
|
}
|
||||||
|
|
||||||
init(host: String, port: Int, logger: SDLLogger) async throws {
|
init(host: String, port: Int, logger: SDLLogger) async throws {
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
|
||||||
@ -139,14 +145,17 @@ actor SDLSuperClientActor {
|
|||||||
self.send(type: .ping, packetId: 0, data: Data())
|
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 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 try await withCheckedThrowingContinuation { cont in
|
||||||
|
self.continuations[packetId] = cont
|
||||||
return promise.futureResult
|
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) {
|
func send(type: SDLPacketType, packetId: UInt32, data: Data) {
|
||||||
@ -155,12 +164,17 @@ actor SDLSuperClientActor {
|
|||||||
|
|
||||||
// 处理回调函数
|
// 处理回调函数
|
||||||
private func fireCallback(message: SDLSuperInboundMessage) {
|
private func fireCallback(message: SDLSuperInboundMessage) {
|
||||||
if let promise = self.callbackPromises[message.msgId] {
|
guard let cont = self.continuations.removeValue(forKey: message.msgId) else {
|
||||||
self.asyncChannel.channel.eventLoop.execute {
|
return
|
||||||
promise.succeed(message)
|
|
||||||
}
|
|
||||||
self.callbackPromises.removeValue(forKey: message.msgId)
|
|
||||||
}
|
}
|
||||||
|
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 {
|
deinit {
|
||||||
|
|||||||
@ -298,7 +298,7 @@ public class SDLContext {
|
|||||||
registerSuper.token = self.config.token
|
registerSuper.token = self.config.token
|
||||||
registerSuper.networkCode = self.config.networkCode
|
registerSuper.networkCode = self.config.networkCode
|
||||||
registerSuper.hostname = self.config.hostname
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user