Skip to content

1:1 call: stable participant's Room gets disconnected when remote peer drops — prevents reconnection #969

@gaurivishnoi16

Description

@gaurivishnoi16

Environment:

  • LiveKit Android SDK: 2.25.3
  • LiveKit Server: (our hosted instance)
  • Android Min SDK: 26, Target SDK: 36

Problem:

In a 1:1 audio/video call, when Participant A loses network (WiFi drops), Participant B's (stable, network is fine) Room also transitions to DISCONNECTED state within ~2
seconds. This makes reconnection impossible because:

  1. Participant A's SDK enters RECONNECTING and attempts ICE restart — this works correctly
  2. But Participant B's Room fires RoomEvent.ParticipantDisconnected followed by RoomEvent.Disconnected
  3. Participant B's Room is now permanently dead (Room.State.DISCONNECTED)
  4. When Participant A's network recovers and LiveKit reconnects them, Participant B cannot detect this because their Room is disconnected — no ParticipantConnected event
    can fire
  5. Participant A reconnects to an empty room (Participant B already left)

Expected behavior (matching iOS SDK):

On the iOS LiveKit SDK, when one participant drops in a 1:1 call:

  • The stable participant's Room stays CONNECTED
  • The remote participant's ConnectionQuality changes to .lost
  • When the dropped participant reconnects via ICE restart, the stable participant receives a ParticipantConnected / track subscribed event
  • The call resumes seamlessly

Reproduction steps:

  1. Connect two Android devices to the same LiveKit room (1:1 call)
  2. Both participants confirmed CONNECTED with EXCELLENT quality
  3. Turn off WiFi on Device A (no cellular fallback — hasActiveNetwork=false)
  4. Observe Device B (stable):
    - RoomEvent.ParticipantDisconnected fires (~2s after drop)
    - RoomEvent.Disconnected fires immediately after
    - Room.state becomes DISCONNECTED permanently
  5. Turn WiFi back on Device A (~5-8 seconds later)
  6. Device A's LiveKit SDK reconnects successfully (RECONNECTING → sees participant briefly)
  7. But Device B's Room is dead — no events fire, call cannot resume

Logs from stable device (Device B):

HEARTBEAT [10s] callState=Connected roomState=CONNECTED participants=1
-- Device A drops WiFi here --
HEARTBEAT [11s] callState=Reconnecting roomState=CONNECTED participants=1
HEARTBEAT [12s] callState=Reconnecting roomState=CONNECTED participants=1
ParticipantDisconnected: participant=... remainingParticipants=0
RoomEvent.Disconnected: LiveKit final disconnect
HEARTBEAT [13s] callState=Reconnecting roomState=DISCONNECTED participants=0
-- Room stays DISCONNECTED forever, even though network is fine --

Logs from dropping device (Device A):

-- WiFi drops --
RoomEvent.Reconnecting: LiveKit SDK ICE restart | attempt=1
HEARTBEAT [8-12s] roomState=RECONNECTING network=Lost
-- WiFi restored --
HEARTBEAT [13s] roomState=RECONNECTING network=Available
-- LiveKit reconnects briefly, sees participant, then disconnects because B already left --
ParticipantDisconnected remainingParticipants=0
RoomEvent.Disconnected

Question:

Is this the intended behavior for 1:1 rooms? On iOS, the stable participant's Room stays connected and only the remote participant's quality degrades. Is there a
configuration option or RoomOption to prevent the server from disconnecting the stable participant's Room when the other peer drops temporarily?

Our backend is configured to keep the room alive for 15 seconds on participant disconnect, but the Android SDK's Room transitions to DISCONNECTED within ~2 seconds on the
stable side.

Workaround we're considering:

Re-creating the Room on the stable device (new LiveKit.create() + room.connect() with the same token) when the Room goes DISCONNECTED during a reconnection grace period.
But this feels like it should be handled at the SDK/server level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions