Skip to content

Call is lost when a participant is added to a one-to-one conversation during a call #19081

Description

@bakiburakogun

Summary

Adding a participant to a one-to-one conversation while a call is running moves everyone to the newly created group conversation, but the call does not continue there. All participants end up out of the call and have to start a new one.

The switchto signal itself works: the clients leave the old room and join the new one within a second. What does not happen is the call in the new conversation.

Setup

  • Nextcloud 34.0.3, Talk 24.0.4
  • External signaling server (nextcloud-spreed-signaling v2.1.1), four servers in one cluster
  • Reproduced with two participants, both on the web client, each connected to a different signaling server

What we see on the signaling servers

15:49:49  session A joined call <old-room>      (one-to-one conversation)
15:50:02  session B joined call <old-room>
          -> third participant is added to the conversation here
15:50:15  session A removed from room <old-room>
15:50:15  session B removed from room <old-room>
15:50:16  session A joined room <new-room>
15:50:17  session B joined room <new-room>
          -> no "joined call <new-room>" for either session

So both clients received and acted on the switchto event, and both are in the new conversation. Neither joins the call there.

Code path we followed

On the server side everything looks as intended. RoomController::createRoom() dispatches RoomExtendedEvent after the new room is created and the invitation list is added, and SignalingListener::notifyRoomExtended() collects the sessions that are in the call and calls BackendNotifier::switchToRoom(). The old room still has its call flag set at that point, so the early return is not taken and the sessions are passed on.

On the client side, switchto is turned into an EventBus switch-to-conversation event, and the handler awaits joinCallAutomatically(token) before navigating. That method starts with

async joinCallAutomatically(token, currentToken = this.token) {
    if (this.isInCall) {
        ...
    }
}

and sets up a watcher that dispatches joinCall for the new token.

What we could not determine

From the server side we cannot tell which of the two happened:

  1. this.isInCall was already false when the handler ran, so nothing was set up at all, or
  2. the watcher fired and the joinCall request failed.

The navigation to the new conversation did happen, which means the handler ran to completion without throwing.

Question

Is the call supposed to continue in the new conversation in this flow? If yes, we are happy to dig further on the client side and prepare a pull request. We can reproduce this on demand and have a four server signaling cluster to test patches on. A pointer on where you would expect the state to be lost would help.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions