anam-org / anam-org/javascript-sdk

JS SDK: handle iceConnectionState=disconnected/failed + attempt client-side ICE restart

Open
#197 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4
Forks
1
Avg merge
6d 6h
Merged PRs (30d)
1

Description

Sub-task of ENG-2180.

What to change

javascript-sdk/src/modules/StreamingClient.ts, the onIceConnectionStateChange() and onConnectionStateChange() handlers (currently lines ~590-610).

Today the SDK only reacts to:

  • iceConnectionState === 'connected' | 'completed' → emit CONNECTION_ESTABLISHED
  • connectionState === 'closed' → emit CONNECTION_CLOSED { WEBRTC_FAILURE }

It has no handler for disconnected or failed. So when a real user's network blips:

  1. T+5s: Chrome flips iceConnectionState=disconnected — SDK does nothing, customer's app doesn't know.
  2. T+15s: Chrome flips connectionState=failed — SDK does nothing, customer's app still doesn't know.
  3. T+20s: engine's 15s grace fires, engine closes the PC, Chrome flips connectionState=closed, SDK finally fires CONNECTION_CLOSED.

For ~15-20s the customer's user sees a frozen avatar with no feedback.

Proposed handlers

private onIceConnectionStateChange() {
  switch (this.peerConnection?.iceConnectionState) {
    case 'connected':
    case 'completed':
      this.publicEventEmitter.emit(AnamEvent.CONNECTION_ESTABLISHED);
      this.startStatsCollection();
      break;
    case 'disconnected':
      // path went bad; customer can show "Reconnecting…" UI
      this.publicEventEmitter.emit(AnamEvent.CONNECTION_UNSTABLE);
      // attempt ICE restart proactively (don't wait for the server)
      this.attemptIceRestart();
      break;
    case 'failed':
      // path is dead from Chrome's perspective; consent checks stopped
      this.publicEventEmitter.emit(AnamEvent.CONNECTION_LOST);
      break;
  }
}

And a corresponding recovered event when the state returns to connected after a disconnected.

ICE restart on the client side

pc.restartIce() (or setLocalDescription({iceRestart: true}) on the offer) triggers a fresh ICE gathering on the client. Combined with the engine-side restart from ENG-2180's engine subticket, this gives us belt-and-suspenders recovery — whoever notices Disconnected first can drive it.

Note: this also needs the engine to handle a client-initiated ICE restart offer cleanly via the existing websocket offer channel.

New public events

Add to AnamEvent:

  • CONNECTION_UNSTABLE — path is degraded, attempting recovery
  • CONNECTION_LOST — path failed; customer should consider this terminal unless CONNECTION_ESTABLISHED fires again
  • (existing CONNECTION_CLOSED stays for final teardown)

Document these in the SDK reference + cookbook — SN and other customers can replace their black-screen experience with a "Reconnecting…" spinner.

Backwards compatibility

New events are additive. Existing CONNECTION_CLOSED behaviour unchanged. SDK consumers that don't subscribe to the new events keep working as today.

Test plan

  • Unit tests for each new state transition emitting the right event.
  • Manual repro using client-issue-test-bench: kill the user's network for 3s, verify CONNECTION_UNSTABLE fires then CONNECTION_ESTABLISHED again on recovery (or CONNECTION_LOST if not).
  • Verify pc.restartIce() correctly produces a renegotiation offer that the engine handles.
  • Test on a TURN-only session and an srflx-only session.
  • Ship behind the customer-facing changelog so SN, DataQueue, etc. know they can wire up CONNECTION_UNSTABLE to their UI.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in javascript-sdk/src/modules/StreamingClient.ts at onIceConnectionStateChange() and onConnectionStateChange(), then inspect AnamEvent and the existing websocket offer path. Run the unit tests for state transitions and use client-issue-test-bench to verify recovery and failure behavior, including TURN-only and srflx-only sessions. Done means the new events, ICE restart negotiation, SDK reference, and cookbook behavior are covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
audio-video-rtc, networking
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.