Skip to content

Commit 9e4c7ce

Browse files
YashJainSCclaude
andcommitted
fix: add timeout on signal connect to prevent reconnect hang
Add a 10s timeout on the signal connect handshake so the reconnect loop can advance when the server never sends a join/reconnect response. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8dc377b commit 9e4c7ce

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import kotlinx.coroutines.delay
4040
import kotlinx.coroutines.flow.MutableSharedFlow
4141
import kotlinx.coroutines.launch
4242
import kotlinx.coroutines.suspendCancellableCoroutine
43+
import kotlinx.coroutines.withTimeout
4344
import kotlinx.serialization.decodeFromString
4445
import kotlinx.serialization.encodeToString
4546
import kotlinx.serialization.json.Json
@@ -186,17 +187,19 @@ constructor(
186187
.addHeader("Authorization", "Bearer $token")
187188
.build()
188189

189-
return suspendCancellableCoroutine { cont ->
190-
// Wait for join response through WebSocketListener
191-
joinContinuation = cont
192-
cont.invokeOnCancellation {
193-
// If the coroutine is cancelled, websocket needs to be cancelled.
194-
// onFailure will handle cleanup.
195-
LKLog.v { "connect cancelled, abort websocket" }
196-
joinContinuation = null
197-
currentWs?.cancel()
190+
return withTimeout(SIGNAL_CONNECT_TIMEOUT.toLong()) {
191+
suspendCancellableCoroutine { cont ->
192+
// Wait for join response through WebSocketListener
193+
joinContinuation = cont
194+
cont.invokeOnCancellation {
195+
// If the coroutine is cancelled, websocket needs to be cancelled.
196+
// onFailure will handle cleanup.
197+
LKLog.v { "connect cancelled, abort websocket" }
198+
joinContinuation = null
199+
currentWs?.cancel()
200+
}
201+
currentWs = websocketFactory.newWebSocket(request, this@SignalClient)
198202
}
199-
currentWs = websocketFactory.newWebSocket(request, this@SignalClient)
200203
}
201204
}
202205

@@ -982,6 +985,7 @@ constructor(
982985
// iceServer("stun:stun3.l.google.com:19302"),
983986
// iceServer("stun:stun4.l.google.com:19302"),
984987
)
988+
private const val SIGNAL_CONNECT_TIMEOUT = 10000
985989
const val CLOSE_REASON_NORMAL_CLOSURE = 1000
986990
const val CLOSE_REASON_PING_TIMEOUT = 3000
987991
const val CLOSE_REASON_WEBSOCKET_FAILURE = 3500

0 commit comments

Comments
 (0)