Title: Call stuck on "Ringing" forever after reconnect: stale room session is reused, no_such_room error is dropped
Labels: bug, 1. to develop, feature: call ☎️
Steps to reproduce
Observed live (Android Talk v24.0.3 release and a 25.1.0-alpha QA build, spreed 24.0.4 + HPB/Janus):
- Join a call from Android (this caches the room session in
ApplicationWideCurrentRoomHolder)
- Leave the app sitting (backgrounded / stuck in a broken call) long enough that the server reaps the room session — spreed advertises
session-ping-limit: 200 and invalidates sessions that stop pinging
- Lose and regain connectivity (WiFi ↔ cellular switch), then re-enter the call
Expected behaviour
The app joins the room and the call. If the cached session is stale, it fetches a fresh one via the joinRoom API and continues. If joining genuinely fails, the user gets an error.
Actual behaviour
The call UI shows "Ringing…" forever. Nothing recovers, no error is shown, and no timeout fires.
Root cause analysis
CallActivity.joinRoomAndCall() only calls the joinRoom API when the cached session is empty (CallActivity.kt:1557); otherwise it reuses ApplicationWideCurrentRoomHolder.getInstance().session — which may have been reaped server-side.
- The HPB rejects the join:
{"type":"error","error":{"code":"no_such_room","message":"The user is not invited to this room."}}
WebSocketInstance.processErrorMessage() handles only no_such_session and hello_expected; no_such_room is logged and dropped — no state change, no retry, no event to the UI.
- The ring timeout (
CallStatus.CALLING_TIMEOUT, CallActivity.kt:2653) is only armed after a successful join (JOINED), so a failed join never times out either.
Evidence
Client (logcat, phone time 12:38:31 — right after a network drop and websocket reconnect):
WebSocketInstance: Sending join room message via websocket
WebSocketInstance: Received error: {"type":"error","error":{"code":"no_such_room","message":"The user is not invited to this room."}}
Earlier the same day, the release build retried a stale join 8 times in 75 seconds (11:23:09–11:24:44), always with the same no_such_room answer — retrying without ever invalidating the cached session.
Server (HPB):
clientsession.go:601: Removed room session 3vUn…: map[error:map[code:no_such_room
message:The user is not invited to this room.] type:error]
hub.go:860: Closing expired session k5l5… (the reaped session the client kept reusing)
Suggested fix
- Handle
no_such_room in the error path: emit an event to the call UI, invalidate the cached room session (ApplicationWideCurrentRoomHolder + CallActivity.callSession), and re-run the joinRoom API to obtain a fresh session before retrying — once or twice, with the fetch as the retry, not the same stale session in a loop.
- If the fresh join also fails, leave the call UI with an error message (never infinite "Ringing").
- Consider arming the calling timeout as soon as the join attempt starts, not only after
JOINED.
Related
Device / version info
- Samsung SM-S938B; Android Talk 24.0.3 and 25.1.0 Alpha 02 (QA); Nextcloud 34, spreed 24.0.4, standalone signaling + Janus.
Title:
Call stuck on "Ringing" forever after reconnect: stale room session is reused, no_such_room error is droppedLabels:
bug,1. to develop,feature: call ☎️Steps to reproduce
Observed live (Android Talk v24.0.3 release and a 25.1.0-alpha QA build, spreed 24.0.4 + HPB/Janus):
ApplicationWideCurrentRoomHolder)session-ping-limit: 200and invalidates sessions that stop pingingExpected behaviour
The app joins the room and the call. If the cached session is stale, it fetches a fresh one via the joinRoom API and continues. If joining genuinely fails, the user gets an error.
Actual behaviour
The call UI shows "Ringing…" forever. Nothing recovers, no error is shown, and no timeout fires.
Root cause analysis
CallActivity.joinRoomAndCall()only calls the joinRoom API when the cached session is empty (CallActivity.kt:1557); otherwise it reusesApplicationWideCurrentRoomHolder.getInstance().session— which may have been reaped server-side.{"type":"error","error":{"code":"no_such_room","message":"The user is not invited to this room."}}WebSocketInstance.processErrorMessage()handles onlyno_such_sessionandhello_expected;no_such_roomis logged and dropped — no state change, no retry, no event to the UI.CallStatus.CALLING_TIMEOUT,CallActivity.kt:2653) is only armed after a successful join (JOINED), so a failed join never times out either.Evidence
Client (logcat, phone time 12:38:31 — right after a network drop and websocket reconnect):
Earlier the same day, the release build retried a stale join 8 times in 75 seconds (11:23:09–11:24:44), always with the same
no_such_roomanswer — retrying without ever invalidating the cached session.Server (HPB):
Suggested fix
no_such_roomin the error path: emit an event to the call UI, invalidate the cached room session (ApplicationWideCurrentRoomHolder+CallActivity.callSession), and re-run the joinRoom API to obtain a fresh session before retrying — once or twice, with the fetch as the retry, not the same stale session in a loop.JOINED.Related
client_not_foundsubscriber failure (separate issue) and the reconnect robustness tracked in No automatic reconnect on instable connection #2368.Device / version info