nextcloud / nextcloud/talk-android
Call fails to join existing call on app launch due to stale roomJoined WebSocket event
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 739
- Forks
- 321
- Avg merge
- 14h 59m
- Merged PRs (30d)
- 151
Description
Steps to reproduce
When launching the app and immediately joining a call that's already in progress, the call sometimes fails to connect with existing participants. The app appears stuck in a "connecting" state. The user must exit the call (and sometimes the channel) and re-enter multiple times before it works.
- Have an active call in progress on another device
- Open the Android app fresh (cold start or returning after being away)
- Tap to join the existing call
- Call appears to connect but never shows other participants — stuck in connecting state
Expected behaviour
The app should join the existing call and connect to all current participants.
Actual behaviour
Call fails to join and gets stuck in 'ringing'
Device brand and model
Samsung Galaxy S23
Android version
16
Nextcloud Talk app version
Master
Nextcloud server version
33
Talk version
23
Custom Signaling server configured
Yes (specify version in Additional Information)
Custom TURN server configured
Yes
Custom STUN server configured
Yes
Android logs
00:15:03.899 onMessageEvent 'hello'
00:15:04.206 onMessageEvent 'roomJoined' currentCallStatus=CONNECTING ← fires BEFORE joinRoomAndCall!
00:15:04.652 hasMCU is true
00:15:04.652 joinRoomAndCall ← too late, stale roomJoined already consumed
The roomJoined event at 00:15:04.206 is stale — it was enqueued before joinRoomAndCall() was called at 00:15:04.652.
Server log
Additional information
Root Cause
The flow on app launch is:
- CallActivity.onCreate() → CONNECTING state
- WebSocket was already connected from a previous session (or ChatActivity had it open)
- Server sends hello event → triggers initiateCall() → fetchSignalingSettings() → ...
- Server also sends a stale roomJoined event from the previous WebSocket session
- The stale roomJoined fires performCall() before joinRoomAndCall() has been called
- Later, joinRoomAndCall() runs and calls WebSocketInstance.joinRoomWithRoomTokenAndSession()
- The WebSocket sees it's already in the same room/session and does a local join without sending anything to the server
- The server never re-sends the participant list because it believes the client is already in the room
- handleCallParticipantsChanged() is never called with existing participants
- State stays at JOINED, never transitions to IN_CONVERSATION
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in CallActivity.onCreate() and trace the named flow through initiateCall(), fetchSignalingSettings(), performCall(), and joinRoomAndCall(). Inspect WebSocketInstance.joinRoomWithRoomTokenAndSession() and handleCallParticipantsChanged() alongside the roomJoined event handling. Done means a cold-start join receives the existing participant list and reaches IN_CONVERSATION instead of remaining in CONNECTING or JOINED.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- audio-video-rtc, mobile-dev, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100