From 436f7e9cca5776a300111b945da3fc2173b858af Mon Sep 17 00:00:00 2001 From: gaoxiaoxiong <745570899@qq.com> Date: Mon, 16 Mar 2026 20:36:58 +0800 Subject: [PATCH 1/3] bugfix: After fixing the failure of RTC reconnection and WebSocket connection, no notification was sent to the upper-layer application. --- .../main/java/io/livekit/android/room/RTCEngine.kt | 13 ++++++++++++- .../java/io/livekit/android/room/SignalClient.kt | 9 ++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt index c3576151..60d86078 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt @@ -146,6 +146,10 @@ internal constructor( ConnectionState.DISCONNECTED -> { LKLog.d { "primary ICE disconnected" } if (oldVal == ConnectionState.CONNECTED) { + LKLog.d { "ready call reconnect()" } + reconnect() + } else if (oldVal == ConnectionState.RESUMING || oldVal == ConnectionState.RECONNECTING) { + LKLog.d { "ICE disconnected during reconnect, retrying reconnect()" } reconnect() } } @@ -313,7 +317,14 @@ internal constructor( if (newState.isConnected()) { connectionState = ConnectionState.CONNECTED } else if (newState.isDisconnected()) { - connectionState = ConnectionState.DISCONNECTED + // Only transition to DISCONNECTED when not already in a reconnection + // intermediate state (RESUMING/RECONNECTING). In those states the + // reconnect flow owns connectionState; overwriting it here would + // silently swallow the disconnect and prevent the app from being notified. + val current = connectionState + if (current != ConnectionState.RESUMING && current != ConnectionState.RECONNECTING) { + connectionState = ConnectionState.DISCONNECTED + } } } diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt index 7c8889b0..98c2fe2f 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt @@ -349,6 +349,9 @@ constructor( LKLog.e(e) { "failed to validate connection" } } + val wasConnected = isConnected + val wasConnecting = joinContinuation != null + if (reason != null) { LKLog.e(t) { "websocket failure: $reason" } val error = Exception(reason) @@ -361,11 +364,11 @@ constructor( } joinContinuation = null - val wasConnected = isConnected - - if (wasConnected) { + if (wasConnected || wasConnecting) { // onClosing/onClosed will not be called after onFailure. // Handle websocket closure here. + // Also handle the case where failure occurs during a reconnect attempt (wasConnecting), + // where isConnected is already false but the upper layer still needs to be notified. handleWebSocketClose( reason = reason ?: response?.toString() ?: t.localizedMessage ?: "websocket failure", code = response?.code ?: CLOSE_REASON_WEBSOCKET_FAILURE, From 27e021484f41db04869dc3022f9ab979030f8c4b Mon Sep 17 00:00:00 2001 From: gaoxiaoxiong <745570899@qq.com> Date: Tue, 24 Mar 2026 14:01:52 +0800 Subject: [PATCH 2/3] bugfix: Remove unnecessary code --- .../src/main/java/io/livekit/android/room/RTCEngine.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt index 60d86078..e485aca3 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt @@ -146,10 +146,6 @@ internal constructor( ConnectionState.DISCONNECTED -> { LKLog.d { "primary ICE disconnected" } if (oldVal == ConnectionState.CONNECTED) { - LKLog.d { "ready call reconnect()" } - reconnect() - } else if (oldVal == ConnectionState.RESUMING || oldVal == ConnectionState.RECONNECTING) { - LKLog.d { "ICE disconnected during reconnect, retrying reconnect()" } reconnect() } } From d7848c65c9dd334bb33237759154042f482ba5d5 Mon Sep 17 00:00:00 2001 From: gaoxiaoxiong <745570899@qq.com> Date: Tue, 24 Mar 2026 14:27:34 +0800 Subject: [PATCH 3/3] bugfix: Remove unnecessary code --- .../src/main/java/io/livekit/android/room/RTCEngine.kt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt index e485aca3..c3576151 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt @@ -313,14 +313,7 @@ internal constructor( if (newState.isConnected()) { connectionState = ConnectionState.CONNECTED } else if (newState.isDisconnected()) { - // Only transition to DISCONNECTED when not already in a reconnection - // intermediate state (RESUMING/RECONNECTING). In those states the - // reconnect flow owns connectionState; overwriting it here would - // silently swallow the disconnect and prevent the app from being notified. - val current = connectionState - if (current != ConnectionState.RESUMING && current != ConnectionState.RECONNECTING) { - connectionState = ConnectionState.DISCONNECTED - } + connectionState = ConnectionState.DISCONNECTED } }