feat: add websocket reconnection logic

This commit is contained in:
2024-07-30 12:44:22 +01:00
parent 0d0e667a96
commit 2e66788e7c

View File

@@ -1,22 +1,41 @@
import Combine import Combine
import Foundation import Foundation
import Network
import SwiftUI import SwiftUI
class LiveStatusManager: ObservableObject { let webSocketMaxReconnectionCount = 3
class LiveStatusManager: NSObject, ObservableObject, URLSessionWebSocketDelegate {
@Published var listenerCount: Int = -1 @Published var listenerCount: Int = -1
@ObservedObject private var playbackManager: PlaybackManager @ObservedObject private var playbackManager: PlaybackManager
private let pathMonitor = NWPathMonitor()
private var ws: URLSessionWebSocketTask? private var ws: URLSessionWebSocketTask?
private var playbackStateObserver: AnyCancellable? private var playbackStateObserver: AnyCancellable?
private var retryCount = 0
init(playbackManager: PlaybackManager) { init(playbackManager: PlaybackManager) {
self.playbackManager = playbackManager self.playbackManager = playbackManager
super.init()
playbackStateObserver = playbackManager.$playbackState.sink { playbackState in playbackStateObserver = playbackManager.$playbackState.sink { playbackState in
self.onPlaybackStateChanged(playbackState) self.onPlaybackStateChanged(playbackState)
} }
pathMonitor.pathUpdateHandler = { path in
self.onNetworkChanged(path)
}
connectToWebSocket() connectToWebSocket()
} }
deinit {
ws?.cancel(with: .goingAway, reason: nil)
pathMonitor.cancel()
}
func connectToWebSocket() { func connectToWebSocket() {
guard let url = URL(string: "wss://infinifi.cafe/ws") else { guard let url = URL(string: "wss://infinifi.cafe/ws") else {
return return
@@ -24,12 +43,35 @@ class LiveStatusManager: ObservableObject {
let req = URLRequest(url: url) let req = URLRequest(url: url)
let ws = URLSession.shared.webSocketTask(with: req) let ws = URLSession.shared.webSocketTask(with: req)
ws.delegate = self
ws.resume() ws.resume()
self.ws = ws self.ws = ws
receiveWebSocketMessage() receiveWebSocketMessage()
} }
func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
if retryCount == webSocketMaxReconnectionCount {
DispatchQueue.main.async {
self.listenerCount = -1
}
} else {
retryCount += 1
connectToWebSocket()
}
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: (any Error)?) {
if retryCount == webSocketMaxReconnectionCount {
DispatchQueue.main.async {
self.listenerCount = -1
}
} else {
retryCount += 1
connectToWebSocket()
}
}
private func receiveWebSocketMessage() { private func receiveWebSocketMessage() {
ws?.receive { result in ws?.receive { result in
switch result { switch result {
@@ -38,6 +80,7 @@ class LiveStatusManager: ObservableObject {
print("failed to received \(err)") print("failed to received \(err)")
#endif #endif
case .success(.string(let msg)): case .success(.string(let msg)):
self.retryCount = 0
self.handleWebSocketMessage(msg) self.handleWebSocketMessage(msg)
default: default:
@@ -72,4 +115,14 @@ class LiveStatusManager: ObservableObject {
break break
} }
} }
private func onNetworkChanged(_ path: NWPath) {
if path.status == .satisfied {
if retryCount > 0 {
retryCount = 0
}
retryCount += 1
connectToWebSocket()
}
}
} }