replace to async method for URLSessionWebSocketTask.receive()

This commit is contained in:
Keita Watanabe 2024-07-25 17:28:51 +09:00
parent 4c1ba2168d
commit c0c6dafd17
3 changed files with 46 additions and 50 deletions

View file

@ -71,7 +71,9 @@ extension IceCubesApp {
.onChange(of: appAccountsManager.currentClient) { _, newValue in .onChange(of: appAccountsManager.currentClient) { _, newValue in
setNewClientsInEnv(client: newValue) setNewClientsInEnv(client: newValue)
if newValue.isAuth { if newValue.isAuth {
watcher.watch(streams: [.user, .direct]) Task {
await watcher.watch(streams: [.user, .direct])
}
} }
} }
} }

View file

@ -44,8 +44,8 @@ struct IceCubesApp: App {
userPreferences.setClient(client: client) userPreferences.setClient(client: client)
Task { Task {
await currentInstance.fetchCurrentInstance() await currentInstance.fetchCurrentInstance()
watcher.setClient(client: client, instanceStreamingURL: currentInstance.instance?.urls?.streamingApi) await watcher.setClient(client: client, instanceStreamingURL: currentInstance.instance?.urls?.streamingApi)
watcher.watch(streams: [.user, .direct]) await watcher.watch(streams: [.user, .direct])
} }
} }
@ -54,10 +54,10 @@ struct IceCubesApp: App {
case .background: case .background:
watcher.stopWatching() watcher.stopWatching()
case .active: case .active:
watcher.watch(streams: [.user, .direct])
UNUserNotificationCenter.current().setBadgeCount(0)
userPreferences.reloadNotificationsCount(tokens: appAccountsManager.availableAccounts.compactMap(\.oauthToken))
Task { Task {
await watcher.watch(streams: [.user, .direct])
try? await UNUserNotificationCenter.current().setBadgeCount(0)
userPreferences.reloadNotificationsCount(tokens: appAccountsManager.availableAccounts.compactMap(\.oauthToken))
await userPreferences.refreshServerPreferences() await userPreferences.refreshServerPreferences()
} }
default: default:

View file

@ -36,16 +36,16 @@ import OSLog
decoder.keyDecodingStrategy = .convertFromSnakeCase decoder.keyDecodingStrategy = .convertFromSnakeCase
} }
public func setClient(client: Client, instanceStreamingURL: URL?) { public func setClient(client: Client, instanceStreamingURL: URL?) async {
if self.client != nil { if self.client != nil {
stopWatching() stopWatching()
} }
self.client = client self.client = client
self.instanceStreamingURL = instanceStreamingURL self.instanceStreamingURL = instanceStreamingURL
connect() await connect()
} }
private func connect() { private func connect() async {
guard let task = try? client?.makeWebSocketTask( guard let task = try? client?.makeWebSocketTask(
endpoint: Streaming.streaming, endpoint: Streaming.streaming,
instanceStreamingURL: instanceStreamingURL instanceStreamingURL: instanceStreamingURL
@ -54,15 +54,15 @@ import OSLog
} }
self.task = task self.task = task
self.task?.resume() self.task?.resume()
receiveMessage() await receiveMessage()
} }
public func watch(streams: [Stream]) { public func watch(streams: [Stream]) async {
if client?.isAuth == false { if client?.isAuth == false {
return return
} }
if task == nil { if task == nil {
connect() await connect()
} }
watchedStreams = streams watchedStreams = streams
for stream in streams { for stream in streams {
@ -83,11 +83,10 @@ import OSLog
} }
} }
private func receiveMessage() { private func receiveMessage() async {
task?.receive(completionHandler: { [weak self] result in do {
guard let self else { return } guard let message = try await task?.receive() else { return }
switch result {
case let .success(message):
switch message { switch message {
case let .string(string): case let .string(string):
do { do {
@ -98,12 +97,10 @@ import OSLog
let rawEvent = try decoder.decode(RawStreamEvent.self, from: data) let rawEvent = try decoder.decode(RawStreamEvent.self, from: data)
logger.info("Stream update: \(rawEvent.event)") logger.info("Stream update: \(rawEvent.event)")
if let event = rawEventToEvent(rawEvent: rawEvent) { if let event = rawEventToEvent(rawEvent: rawEvent) {
Task { @MainActor in events.append(event)
self.events.append(event) latestEvent = event
self.latestEvent = event
if let event = event as? StreamEventNotification, event.notification.status?.visibility != .direct { if let event = event as? StreamEventNotification, event.notification.status?.visibility != .direct {
self.unreadNotificationsCount += 1 unreadNotificationsCount += 1
}
} }
} }
} catch { } catch {
@ -114,18 +111,15 @@ import OSLog
break break
} }
receiveMessage() await receiveMessage()
} catch {
case .failure: try? await Task.sleep(nanoseconds: UInt64(retryDelay * 1000 * 1000 * 1000))
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(retryDelay)) { retryDelay += 30
self.retryDelay += 30 stopWatching()
self.stopWatching() await connect()
self.connect() await watch(streams: watchedStreams)
self.watch(streams: self.watchedStreams)
} }
} }
})
}
private func rawEventToEvent(rawEvent: RawStreamEvent) -> (any StreamEvent)? { private func rawEventToEvent(rawEvent: RawStreamEvent) -> (any StreamEvent)? {
guard let payloadData = rawEvent.payload.data(using: .utf8) else { guard let payloadData = rawEvent.payload.data(using: .utf8) else {