mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-02 19:49:23 +00:00
Always consider multi-SFU mode enabled when using sticky events
CallViewModel would pass the wrong transport to enterRtcSession when the user enabled sticky events but didn't manually enable multi-SFU mode as well. This likely would've added some confusion to our attempts to test these modes.
This commit is contained in:
@@ -20,7 +20,6 @@ import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget";
|
|||||||
import { MatrixRTCTransportMissingError } from "./utils/errors";
|
import { MatrixRTCTransportMissingError } from "./utils/errors";
|
||||||
import { getUrlParams } from "./UrlParams";
|
import { getUrlParams } from "./UrlParams";
|
||||||
import { getSFUConfigWithOpenID } from "./livekit/openIDSFU.ts";
|
import { getSFUConfigWithOpenID } from "./livekit/openIDSFU.ts";
|
||||||
import { preferStickyEvents } from "./settings/settings.ts";
|
|
||||||
|
|
||||||
const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
|
const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
|
||||||
|
|
||||||
@@ -100,12 +99,11 @@ export async function makeTransport(
|
|||||||
|
|
||||||
export interface EnterRTCSessionOptions {
|
export interface EnterRTCSessionOptions {
|
||||||
encryptMedia: boolean;
|
encryptMedia: boolean;
|
||||||
// TODO: remove this flag, the new membership manager is stable enough
|
|
||||||
useNewMembershipManager?: boolean;
|
|
||||||
// TODO: remove this flag, to-device transport is stable enough now
|
// TODO: remove this flag, to-device transport is stable enough now
|
||||||
useExperimentalToDeviceTransport?: boolean;
|
useExperimentalToDeviceTransport?: boolean;
|
||||||
/** EXPERIMENTAL: If true, will use the multi-sfu codepath where each member connects to its SFU instead of everyone connecting to an elected on. */
|
/** EXPERIMENTAL: If true, will use the multi-sfu codepath where each member connects to its SFU instead of everyone connecting to an elected on. */
|
||||||
useMultiSfu?: boolean;
|
useMultiSfu: boolean;
|
||||||
|
preferStickyEvents: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,14 +115,13 @@ export interface EnterRTCSessionOptions {
|
|||||||
export async function enterRTCSession(
|
export async function enterRTCSession(
|
||||||
rtcSession: MatrixRTCSession,
|
rtcSession: MatrixRTCSession,
|
||||||
transport: LivekitTransport,
|
transport: LivekitTransport,
|
||||||
options: EnterRTCSessionOptions = {
|
{
|
||||||
encryptMedia: true,
|
encryptMedia,
|
||||||
useExperimentalToDeviceTransport: false,
|
useExperimentalToDeviceTransport = false,
|
||||||
useMultiSfu: true,
|
useMultiSfu,
|
||||||
},
|
preferStickyEvents,
|
||||||
|
}: EnterRTCSessionOptions,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { encryptMedia, useExperimentalToDeviceTransport = false } = options;
|
|
||||||
const useMultiSfu = preferStickyEvents.getValue() || options.useMultiSfu;
|
|
||||||
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
||||||
PosthogAnalytics.instance.eventCallStarted.track(rtcSession.room.roomId);
|
PosthogAnalytics.instance.eventCallStarted.track(rtcSession.room.roomId);
|
||||||
|
|
||||||
@@ -158,7 +155,7 @@ export async function enterRTCSession(
|
|||||||
membershipEventExpiryMs:
|
membershipEventExpiryMs:
|
||||||
matrixRtcSessionConfig?.membership_event_expiry_ms,
|
matrixRtcSessionConfig?.membership_event_expiry_ms,
|
||||||
useExperimentalToDeviceTransport,
|
useExperimentalToDeviceTransport,
|
||||||
unstableSendStickyEvents: preferStickyEvents.getValue(),
|
unstableSendStickyEvents: preferStickyEvents,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (widget) {
|
if (widget) {
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import {
|
|||||||
duplicateTiles,
|
duplicateTiles,
|
||||||
multiSfu,
|
multiSfu,
|
||||||
playReactionsSound,
|
playReactionsSound,
|
||||||
|
preferStickyEvents,
|
||||||
showReactions,
|
showReactions,
|
||||||
} from "../settings/settings";
|
} from "../settings/settings";
|
||||||
import { isFirefox } from "../Platform";
|
import { isFirefox } from "../Platform";
|
||||||
@@ -262,23 +263,32 @@ export class CallViewModel extends ViewModel {
|
|||||||
/**
|
/**
|
||||||
* Lists the transports used by ourselves, plus all other MatrixRTC session
|
* Lists the transports used by ourselves, plus all other MatrixRTC session
|
||||||
* members. For completeness this also lists the preferred transport and
|
* members. For completeness this also lists the preferred transport and
|
||||||
* whether we are in multi-SFU mode (because advertisedTransport$ wants to
|
* whether we are in multi-SFU mode or sticky events mode (because
|
||||||
* read them at the same time, and bundling data together when it might change
|
* advertisedTransport$ wants to read them at the same time, and bundling data
|
||||||
* together is what you have to do in RxJS to avoid reading inconsistent state
|
* together when it might change together is what you have to do in RxJS to
|
||||||
* or observing too many changes.)
|
* avoid reading inconsistent state or observing too many changes.)
|
||||||
*/
|
*/
|
||||||
private readonly transports$: Behavior<{
|
private readonly transports$: Behavior<{
|
||||||
local: Async<LivekitTransport>;
|
local: Async<LivekitTransport>;
|
||||||
remote: { membership: CallMembership; transport: LivekitTransport }[];
|
remote: { membership: CallMembership; transport: LivekitTransport }[];
|
||||||
preferred: Async<LivekitTransport>;
|
preferred: Async<LivekitTransport>;
|
||||||
multiSfu: boolean;
|
multiSfu: boolean;
|
||||||
|
preferStickyEvents: boolean;
|
||||||
} | null> = this.scope.behavior(
|
} | null> = this.scope.behavior(
|
||||||
this.joined$.pipe(
|
this.joined$.pipe(
|
||||||
switchMap((joined) =>
|
switchMap((joined) =>
|
||||||
joined
|
joined
|
||||||
? combineLatest(
|
? combineLatest(
|
||||||
[this.preferredTransport$, this.memberships$, multiSfu.value$],
|
[
|
||||||
(preferred, memberships, multiSfu) => {
|
this.preferredTransport$,
|
||||||
|
this.memberships$,
|
||||||
|
multiSfu.value$,
|
||||||
|
preferStickyEvents.value$,
|
||||||
|
],
|
||||||
|
(preferred, memberships, preferMultiSfu, preferStickyEvents) => {
|
||||||
|
// Multi-SFU must be implicitly enabled when using sticky events
|
||||||
|
const multiSfu = preferStickyEvents || preferMultiSfu;
|
||||||
|
|
||||||
const oldestMembership =
|
const oldestMembership =
|
||||||
this.matrixRTCSession.getOldestMembership();
|
this.matrixRTCSession.getOldestMembership();
|
||||||
const remote = memberships.flatMap((m) => {
|
const remote = memberships.flatMap((m) => {
|
||||||
@@ -289,6 +299,7 @@ export class CallViewModel extends ViewModel {
|
|||||||
? [{ membership: m, transport: t }]
|
? [{ membership: m, transport: t }]
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
let local = preferred;
|
let local = preferred;
|
||||||
if (!multiSfu) {
|
if (!multiSfu) {
|
||||||
const oldest = this.matrixRTCSession.getOldestMembership();
|
const oldest = this.matrixRTCSession.getOldestMembership();
|
||||||
@@ -299,6 +310,7 @@ export class CallViewModel extends ViewModel {
|
|||||||
local = ready(selection);
|
local = ready(selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local.state === "error") {
|
if (local.state === "error") {
|
||||||
this._configError$.next(
|
this._configError$.next(
|
||||||
local.value instanceof ElementCallError
|
local.value instanceof ElementCallError
|
||||||
@@ -306,7 +318,14 @@ export class CallViewModel extends ViewModel {
|
|||||||
: new UnknownCallError(local.value),
|
: new UnknownCallError(local.value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return { local, remote, preferred, multiSfu };
|
|
||||||
|
return {
|
||||||
|
local,
|
||||||
|
remote,
|
||||||
|
preferred,
|
||||||
|
multiSfu,
|
||||||
|
preferStickyEvents,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: of(null),
|
: of(null),
|
||||||
@@ -336,10 +355,11 @@ export class CallViewModel extends ViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The transport we should advertise in our MatrixRTC membership (plus whether
|
* The transport we should advertise in our MatrixRTC membership (plus whether
|
||||||
* it is a multi-SFU transport).
|
* it is a multi-SFU transport and whether we should use sticky events).
|
||||||
*/
|
*/
|
||||||
private readonly advertisedTransport$: Behavior<{
|
private readonly advertisedTransport$: Behavior<{
|
||||||
multiSfu: boolean;
|
multiSfu: boolean;
|
||||||
|
preferStickyEvents: boolean;
|
||||||
transport: LivekitTransport;
|
transport: LivekitTransport;
|
||||||
} | null> = this.scope.behavior(
|
} | null> = this.scope.behavior(
|
||||||
this.transports$.pipe(
|
this.transports$.pipe(
|
||||||
@@ -348,6 +368,7 @@ export class CallViewModel extends ViewModel {
|
|||||||
transports.preferred.state === "ready"
|
transports.preferred.state === "ready"
|
||||||
? {
|
? {
|
||||||
multiSfu: transports.multiSfu,
|
multiSfu: transports.multiSfu,
|
||||||
|
preferStickyEvents: transports.preferStickyEvents,
|
||||||
// In non-multi-SFU mode we should always advertise the preferred
|
// In non-multi-SFU mode we should always advertise the preferred
|
||||||
// SFU to minimize the number of membership updates
|
// SFU to minimize the number of membership updates
|
||||||
transport: transports.multiSfu
|
transport: transports.multiSfu
|
||||||
@@ -358,6 +379,7 @@ export class CallViewModel extends ViewModel {
|
|||||||
),
|
),
|
||||||
distinctUntilChanged<{
|
distinctUntilChanged<{
|
||||||
multiSfu: boolean;
|
multiSfu: boolean;
|
||||||
|
preferStickyEvents: boolean;
|
||||||
transport: LivekitTransport;
|
transport: LivekitTransport;
|
||||||
} | null>(deepCompare),
|
} | null>(deepCompare),
|
||||||
),
|
),
|
||||||
@@ -1800,8 +1822,8 @@ export class CallViewModel extends ViewModel {
|
|||||||
await enterRTCSession(this.matrixRTCSession, advertised.transport, {
|
await enterRTCSession(this.matrixRTCSession, advertised.transport, {
|
||||||
encryptMedia: this.options.encryptionSystem.kind !== E2eeType.NONE,
|
encryptMedia: this.options.encryptionSystem.kind !== E2eeType.NONE,
|
||||||
useExperimentalToDeviceTransport: true,
|
useExperimentalToDeviceTransport: true,
|
||||||
useNewMembershipManager: true,
|
|
||||||
useMultiSfu: advertised.multiSfu,
|
useMultiSfu: advertised.multiSfu,
|
||||||
|
preferStickyEvents: advertised.preferStickyEvents,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("Error entering RTC session", e);
|
logger.error("Error entering RTC session", e);
|
||||||
|
|||||||
Reference in New Issue
Block a user