diff --git a/Sources/LiveKit/Core/Room+Engine.swift b/Sources/LiveKit/Core/Room+Engine.swift index 4c9b1b5f0..ec08ea0dd 100644 --- a/Sources/LiveKit/Core/Room+Engine.swift +++ b/Sources/LiveKit/Core/Room+Engine.swift @@ -268,7 +268,7 @@ extension Room { log("\(_state.connectStopwatch)") } - func startReconnect(reason: StartReconnectReason, nextReconnectMode: ReconnectMode? = nil) async throws { + func startReconnect(reason: StartReconnectReason, nextReconnectMode: ReconnectMode = .none) async throws { log("[Connect] Starting, reason: \(reason)") guard case .connected = _state.connectionState else { @@ -286,7 +286,7 @@ extension Room { throw LiveKitError(.invalidState) } - guard _state.isReconnectingWithMode == nil else { + guard _state.isReconnectingWithMode == .none else { log("[Connect] Reconnect already in progress...", .warning) throw LiveKitError(.invalidState) } @@ -368,7 +368,8 @@ extension Room { return delay }) { currentAttempt, totalAttempts in // Not reconnecting state anymore - guard let currentMode = self._state.isReconnectingWithMode else { + let currentMode = self._state.isReconnectingWithMode + guard currentMode != .none else { self.log("[Connect] Not in reconnect state anymore, exiting retry cycle.") return } @@ -379,14 +380,14 @@ extension Room { self.log("[Connect] Starting retry attempt \(currentAttempt)/\(totalAttempts) with mode: \(currentMode)") // Try full reconnect for the final attempt - if totalAttempts == currentAttempt, self._state.nextReconnectMode == nil { + if totalAttempts == currentAttempt, self._state.nextReconnectMode == .none { self._state.mutate { $0.nextReconnectMode = .full } } let mode: ReconnectMode = self._state.mutate { let mode: ReconnectMode = ($0.nextReconnectMode == .full || $0.isReconnectingWithMode == .full) ? .full : .quick $0.isReconnectingWithMode = mode - $0.nextReconnectMode = nil + $0.nextReconnectMode = .none return mode } @@ -409,8 +410,8 @@ extension Room { log("[Connect] Sequence completed") _state.mutate { $0.connectionState = .connected - $0.isReconnectingWithMode = nil - $0.nextReconnectMode = nil + $0.isReconnectingWithMode = .none + $0.nextReconnectMode = .none } } catch { log("[Connect] Sequence failed with error: \(error)") diff --git a/Sources/LiveKit/Core/Room+EngineDelegate.swift b/Sources/LiveKit/Core/Room+EngineDelegate.swift index 85d699dff..4b4c7f903 100644 --- a/Sources/LiveKit/Core/Room+EngineDelegate.swift +++ b/Sources/LiveKit/Core/Room+EngineDelegate.swift @@ -87,11 +87,9 @@ extension Room { } // Notify when reconnection mode changes - if state.isReconnectingWithMode != oldState.isReconnectingWithMode, - let mode = state.isReconnectingWithMode - { + if state.isReconnectingWithMode != oldState.isReconnectingWithMode { delegates.notify(label: { "room.didUpdate reconnectionMode: \(String(describing: state.isReconnectingWithMode)) oldValue: \(String(describing: oldState.isReconnectingWithMode))" }) { - $0.room?(self, didUpdateReconnectMode: mode) + $0.room?(self, didUpdateReconnectMode: state.isReconnectingWithMode) } } diff --git a/Sources/LiveKit/Core/Room.swift b/Sources/LiveKit/Core/Room.swift index 956d41a72..6c19ea70e 100644 --- a/Sources/LiveKit/Core/Room.swift +++ b/Sources/LiveKit/Core/Room.swift @@ -162,8 +162,8 @@ public class Room: NSObject, @unchecked Sendable, ObservableObject, Loggable { var url: URL? var token: String? // preferred reconnect mode which will be used only for next attempt - var nextReconnectMode: ReconnectMode? - var isReconnectingWithMode: ReconnectMode? + var nextReconnectMode: ReconnectMode = .none + var isReconnectingWithMode: ReconnectMode = .none var connectionState: ConnectionState = .disconnected var disconnectError: LiveKitError? var connectStopwatch = Stopwatch(label: "connect") @@ -269,7 +269,7 @@ public class Room: NSObject, @unchecked Sendable, ObservableObject, Loggable { } } - if newState.connectionState == .reconnecting, newState.isReconnectingWithMode == nil { + if newState.connectionState == .reconnecting, newState.isReconnectingWithMode == .none { self.log("reconnectMode should not be .none", .error) } diff --git a/Sources/LiveKit/Core/SignalClient.swift b/Sources/LiveKit/Core/SignalClient.swift index f119ae07a..c73ce92b8 100644 --- a/Sources/LiveKit/Core/SignalClient.swift +++ b/Sources/LiveKit/Core/SignalClient.swift @@ -118,13 +118,13 @@ actor SignalClient: Loggable { func connect(_ url: URL, _ token: String, connectOptions: ConnectOptions? = nil, - reconnectMode: ReconnectMode? = nil, + reconnectMode: ReconnectMode = .none, participantSid: Participant.Sid? = nil, adaptiveStream: Bool) async throws -> ConnectResponse { await cleanUp() - if let reconnectMode { + if reconnectMode != .none { log("[Connect] mode: \(String(describing: reconnectMode))") } @@ -135,13 +135,13 @@ actor SignalClient: Loggable { participantSid: participantSid, adaptiveStream: adaptiveStream) - if reconnectMode != nil { + if reconnectMode != .none { log("[Connect] with url: \(url)") } else { log("Connecting with url: \(url)") } - _state.mutate { $0.connectionState = (reconnectMode != nil ? .reconnecting : .connecting) } + _state.mutate { $0.connectionState = (reconnectMode != .none ? .reconnecting : .connecting) } do { let socket = try await WebSocket(url: url, connectOptions: connectOptions) @@ -177,7 +177,7 @@ actor SignalClient: Loggable { } // Skip validation if reconnect mode - if reconnectMode != nil { + if reconnectMode != .none { await cleanUp(withError: error) throw error } diff --git a/Sources/LiveKit/Extensions/CustomStringConvertible.swift b/Sources/LiveKit/Extensions/CustomStringConvertible.swift index aa39a28a6..7169f3aec 100644 --- a/Sources/LiveKit/Extensions/CustomStringConvertible.swift +++ b/Sources/LiveKit/Extensions/CustomStringConvertible.swift @@ -145,6 +145,7 @@ extension ConnectionState: CustomStringConvertible { extension ReconnectMode: CustomStringConvertible { public var description: String { switch self { + case .none: return ".none" case .quick: return ".quick" case .full: return ".full" } diff --git a/Sources/LiveKit/Support/Utils.swift b/Sources/LiveKit/Support/Utils.swift index e83720286..952eb4a27 100644 --- a/Sources/LiveKit/Support/Utils.swift +++ b/Sources/LiveKit/Support/Utils.swift @@ -137,7 +137,7 @@ class Utils { _ url: URL, _ token: String, connectOptions: ConnectOptions? = nil, - reconnectMode: ReconnectMode? = nil, + reconnectMode: ReconnectMode = .none, participantSid: Participant.Sid? = nil, adaptiveStream: Bool, validate: Bool = false, diff --git a/Sources/LiveKit/Types/ConnectionState.swift b/Sources/LiveKit/Types/ConnectionState.swift index a7fab0787..8c6477304 100644 --- a/Sources/LiveKit/Types/ConnectionState.swift +++ b/Sources/LiveKit/Types/ConnectionState.swift @@ -18,6 +18,9 @@ import Foundation @objc public enum ReconnectMode: Int, Sendable { + /// Not trying to reconnect + case none + /// Quick reconnection mode attempts to maintain the same session, reusing existing /// transport connections and published tracks. This is faster but may not succeed /// in all network conditions.