mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Fall back to publishing on a remote SFU if possible
Port of edf1feae from johannes/rtc-remote-publish onto the SDK split,
where
the MatrixRTC logic lives in sdk/ rather than src/state/CallViewModel/.
Where the original lands:
- getLocalTransport's remote fallback: the LiveKit backend's new
findRemotePublishTransport (sdk/src/media-backend/livekit/
RemotePublishTransport.ts), which tries the candidates from the
js-sdk's
getRemoteLivekitPublishCandidates oldest first and keeps the first
whose
homeserver issues a token with the publish grant.
discoverLocalTransport
asks the backend for it after the host's fallback, with a snapshot of
the
session's memberships from RTCParticipation, and throws
MatrixRTCTransportMissingError where that finds nothing too. Transport
discovery stays backend neutral: the MSC4195 token check is the
backend's.
- LocalMember's "no delegation on a remote SFU" and the custom
transport's
server_name: LivekitBackend.prepareLocalTransport locates the
transport on
the homeserver it names (serverNameOfTransport) and skips the
delegation
probe where that is not our own.
- SessionBehaviors' membership.getTransportServerName: the same helper
in
LivekitBackend.mediaFor.
- decodeSFUJWTPayload, SFUJWTPayload.video.canPublish and the exported
isCsApiUnavailable: sdk/src/media-backend/livekit/auth/.
- DeveloperSettingsTab, the widget capabilities, the locale string and
the
js-sdk pin (9405287c, 44.0.0): applied as is. The error boundary
snapshots follow the string.
Tests: the LocalTransport cases go to RemotePublishTransport.test.ts and
LocalTransport.test.ts, the LocalMember remote case and the
SessionBehaviors
server-name case to LivekitBackend.test.ts, plus the memberships
snapshot in
RTCParticipation.test.ts.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
4b73ce68e3
commit
8638d4f159
+11
-2
@@ -101,6 +101,8 @@ LiveKit participants.
|
||||
│ create ───▶│ │ │
|
||||
│ │ GET rtc/transports (session) ────────▶│ │
|
||||
│ │◀── first transport of the backend's type │
|
||||
│ │ (none: findRemotePublishTransport, │ │
|
||||
│ │ a member's SFU we may publish on) ─▶│ │
|
||||
│ │ prepareLocalTransport (backend): │ │
|
||||
│ │ publisher token: CS API get_token, │ │
|
||||
│ │ or OpenID token then /sfu/get ─────▶│ │
|
||||
@@ -537,6 +539,10 @@ type MemberMediaFields = Pick<RTCMember, "tracks$" | "encryptionError$">;
|
||||
|
||||
export interface MediaBackend {
|
||||
readonly transportType: string; // "livekit"
|
||||
/** Another member's transport we may publish on, where the client found none. */
|
||||
findRemotePublishTransport(
|
||||
memberships: CallMembership[],
|
||||
): Promise<Transport | null>;
|
||||
/** Authenticate with the transport the client found; the probe for delegation runs here. */
|
||||
prepareLocalTransport(
|
||||
transport: Transport,
|
||||
@@ -556,7 +562,9 @@ export interface MediaBackend {
|
||||
```
|
||||
|
||||
What stays on the client's side: discovery of the local transport from the
|
||||
homeserver's list (a homeserver endpoint, so not a backend's), the membership
|
||||
homeserver's list (a homeserver endpoint, so not a backend's), asking the
|
||||
backend for another member's transport only where that list and the host's
|
||||
fallback are empty, the membership
|
||||
state machine in `LocalMembership.ts` and its combination with
|
||||
`local.connectionState$` into `state$`, the choice of delayed leave timings,
|
||||
mapping a data packet's sender to a member, and the transport registry, which keys on the raw
|
||||
@@ -566,7 +574,8 @@ transport serialised with sorted keys and derives `connectedTransports$` and eac
|
||||
The backend's context carries no Matrix client and no membership list. A backend
|
||||
that needs the client takes a `Pick` of exactly what it calls in its own options
|
||||
(`createLivekitBackend(scope, context, { client, mediaQuality })`),
|
||||
and learns of remote members only through `mediaFor$`, registering each
|
||||
and learns of remote members only through `mediaFor$` and the one membership
|
||||
snapshot `findRemotePublishTransport` is handed, registering each
|
||||
membership's transport for as long as the member's scope lives. Media keys reach
|
||||
it as a stream, `mediaKeys$`, replayed on subscribe; the js-sdk session never
|
||||
does. A host supplies its own backend through `MatrixRTCClientOptions.backend`;
|
||||
|
||||
Reference in New Issue
Block a user