cleanup based on new js-sdk impl
This commit is contained in:
@@ -415,17 +415,18 @@ export function createCallViewModel$(
|
||||
const ownMembershipIdentity: CallMembershipIdentityParts = {
|
||||
userId,
|
||||
deviceId,
|
||||
// TODO look into this!!!
|
||||
memberId: `${userId}:${deviceId}`,
|
||||
};
|
||||
|
||||
const useOldJwtEndpoint$ = scope.behavior(
|
||||
options.matrixRTCMode$.pipe(map((v) => v !== MatrixRTCMode.Matrix_2_0)),
|
||||
);
|
||||
const localTransport$ = createLocalTransport$({
|
||||
scope: scope,
|
||||
memberships$: memberships$,
|
||||
ownMembershipIdentity,
|
||||
client,
|
||||
useMatrix2$: scope.behavior(
|
||||
options.matrixRTCMode$.pipe(map((v) => v === MatrixRTCMode.Matrix_2_0)),
|
||||
),
|
||||
delayId$: scope.behavior(
|
||||
(
|
||||
fromEvent(
|
||||
@@ -436,6 +437,7 @@ export function createCallViewModel$(
|
||||
matrixRTCSession.delayId ?? null,
|
||||
),
|
||||
roomId: matrixRoom.roomId,
|
||||
useOldJwtEndpoint$,
|
||||
useOldestMember$: scope.behavior(
|
||||
options.matrixRTCMode$.pipe(map((v) => v === MatrixRTCMode.Legacy)),
|
||||
),
|
||||
@@ -455,29 +457,19 @@ export function createCallViewModel$(
|
||||
const connectionManager = createConnectionManager$({
|
||||
scope: scope,
|
||||
connectionFactory: connectionFactory,
|
||||
inputTransports$: scope.behavior(
|
||||
combineLatest(
|
||||
[
|
||||
localTransport$.pipe(
|
||||
catchError((e: unknown) => {
|
||||
logger.info(
|
||||
"dont pass local transport to createConnectionManager$. localTransport$ threw an error",
|
||||
e,
|
||||
);
|
||||
return of(null);
|
||||
}),
|
||||
),
|
||||
membershipsAndTransports.transports$,
|
||||
],
|
||||
(localTransport, transports) => {
|
||||
const localTransportAsArray = localTransport ? [localTransport] : [];
|
||||
return transports.mapInner((transports) => [
|
||||
...localTransportAsArray,
|
||||
...transports,
|
||||
]);
|
||||
},
|
||||
localTransport$: scope.behavior(
|
||||
localTransport$.pipe(
|
||||
catchError((e: unknown) => {
|
||||
logger.info(
|
||||
"could not pass local transport to createConnectionManager$. localTransport$ threw an error",
|
||||
e,
|
||||
);
|
||||
return of(null);
|
||||
}),
|
||||
),
|
||||
),
|
||||
remoteTransports$: membershipsAndTransports.transports$,
|
||||
forceOldJwtEndpointForLocalTransport$: useOldJwtEndpoint$,
|
||||
logger: logger,
|
||||
ownMembershipIdentity,
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ describe("LocalTransport", () => {
|
||||
getDeviceId: vi.fn(),
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
useMatrix2$: constant(false),
|
||||
useOldJwtEndpoint$: constant(false),
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
await flushPromises();
|
||||
@@ -76,7 +76,7 @@ describe("LocalTransport", () => {
|
||||
getDeviceId: vi.fn(),
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
useMatrix2$: constant(false),
|
||||
useOldJwtEndpoint$: constant(false),
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
localTransport$.subscribe(
|
||||
@@ -116,7 +116,7 @@ describe("LocalTransport", () => {
|
||||
baseUrl: "https://lk.example.org",
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
useMatrix2$: constant(false),
|
||||
useOldJwtEndpoint$: constant(false),
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("LocalTransport", () => {
|
||||
baseUrl: "https://lk.example.org",
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
useMatrix2$: constant(false),
|
||||
useOldJwtEndpoint$: constant(false),
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
} from "../../../livekit/openIDSFU.ts";
|
||||
import { areLivekitTransportsEqual } from "../remoteMembers/MatrixLivekitMembers.ts";
|
||||
import { customLivekitUrl } from "../../../settings/settings.ts";
|
||||
import { type LivekitTransportWithVersion } from "../remoteMembers/ConnectionManager.ts";
|
||||
|
||||
const logger = rootLogger.getChild("[LocalTransport]");
|
||||
|
||||
@@ -51,7 +50,7 @@ interface Props {
|
||||
client: Pick<MatrixClient, "getDomain" | "baseUrl"> & OpenIDClientParts;
|
||||
roomId: string;
|
||||
useOldestMember$: Behavior<boolean>;
|
||||
useMatrix2$: Behavior<boolean>;
|
||||
useOldJwtEndpoint$: Behavior<boolean>;
|
||||
delayId$: Behavior<string | null>;
|
||||
}
|
||||
|
||||
@@ -62,6 +61,11 @@ interface Props {
|
||||
* @prop useOldestMember Whether to use the same transport as the oldest member.
|
||||
* This will only update once the first oldest member appears. Will not recompute if the oldest member leaves.
|
||||
*
|
||||
* @prop useOldJwtEndpoint$ Whether to set forceOldJwtEndpoint the use the old JWT endpoint.
|
||||
* This is used when the connection manager needs to know if it has to use the legacy endpoint which implies a string concatenated rtcBackendIdentity.
|
||||
* (which is expected for non sticky event based rtc member events)
|
||||
* @returns Behavior<(LivekitTransport & { forceOldJwtEndpoint: boolean }) | null> The `forceOldJwtEndpoint` field is added to let the connection EncryptionManager
|
||||
* know that this transport is for the local member and it IS RELEVANT which jwt endpoint to use. (for the local member transport, we need to know which jwt endpoint to use)
|
||||
* @throws MatrixRTCTransportMissingError | FailToGetOpenIdToken
|
||||
*/
|
||||
export const createLocalTransport$ = ({
|
||||
@@ -71,21 +75,20 @@ export const createLocalTransport$ = ({
|
||||
client,
|
||||
roomId,
|
||||
useOldestMember$,
|
||||
useMatrix2$,
|
||||
useOldJwtEndpoint$,
|
||||
delayId$,
|
||||
}: Props): Behavior<LivekitTransportWithVersion | null> => {
|
||||
}: Props): Behavior<LivekitTransport | null> => {
|
||||
/**
|
||||
* The transport over which we should be actively publishing our media.
|
||||
* undefined when not joined.
|
||||
*/
|
||||
const oldestMemberTransport$ = scope.behavior(
|
||||
memberships$.pipe(
|
||||
map((memberships) => {
|
||||
combineLatest([memberships$, useOldJwtEndpoint$]).pipe(
|
||||
map(([memberships, forceOldJwtEndpoint]) => {
|
||||
const oldestMember = memberships.value[0];
|
||||
const t = oldestMember?.getTransport(memberships.value[0]);
|
||||
if (!t) return null;
|
||||
// Here we will use the matrix2 information from the oldest member transport.
|
||||
return { ...t, useMatrix2: oldestMember.kind === "rtc" };
|
||||
const transport = oldestMember?.getTransport(memberships.value[0]);
|
||||
if (!transport) return null;
|
||||
return { ...transport, forceOldJwtEndpoint };
|
||||
}),
|
||||
first((t) => t != null && isLivekitTransport(t)),
|
||||
),
|
||||
@@ -98,24 +101,23 @@ export const createLocalTransport$ = ({
|
||||
*
|
||||
* @throws MatrixRTCTransportMissingError | FailToGetOpenIdToken
|
||||
*/
|
||||
const preferredTransport$: Behavior<LivekitTransportWithVersion | null> =
|
||||
scope.behavior(
|
||||
combineLatest([customLivekitUrl.value$, useMatrix2$, delayId$]).pipe(
|
||||
switchMap(([customUrl, useMatrix2, delayId]) =>
|
||||
from(
|
||||
makeTransport(
|
||||
client,
|
||||
ownMembershipIdentity,
|
||||
roomId,
|
||||
customUrl,
|
||||
useMatrix2,
|
||||
delayId ?? undefined,
|
||||
),
|
||||
const preferredTransport$: Behavior<LivekitTransport | null> = scope.behavior(
|
||||
combineLatest([customLivekitUrl.value$, delayId$, useOldJwtEndpoint$]).pipe(
|
||||
switchMap(([customUrl, delayId, forceOldJwtEndpoint]) =>
|
||||
from(
|
||||
makeTransport(
|
||||
client,
|
||||
ownMembershipIdentity,
|
||||
roomId,
|
||||
customUrl,
|
||||
forceOldJwtEndpoint,
|
||||
delayId ?? undefined,
|
||||
),
|
||||
),
|
||||
),
|
||||
null,
|
||||
);
|
||||
),
|
||||
null,
|
||||
);
|
||||
|
||||
/**
|
||||
* The chosen transport we should advertise in our MatrixRTC membership.
|
||||
@@ -131,7 +133,7 @@ export const createLocalTransport$ = ({
|
||||
? (oldestMemberTransport ?? preferredTransport)
|
||||
: preferredTransport,
|
||||
),
|
||||
distinctUntilChanged(areLivekitTransportsEqual),
|
||||
distinctUntilChanged((t1, t2) => areLivekitTransportsEqual(t1, t2)),
|
||||
),
|
||||
);
|
||||
};
|
||||
@@ -142,6 +144,8 @@ const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
|
||||
*
|
||||
* @param client
|
||||
* @param roomId
|
||||
* @param useMatrix2 This implies using the matrix2 jwt endpoint (including delayed event delegation of the jwt token)
|
||||
* @param delayId
|
||||
* @returns
|
||||
* @throws MatrixRTCTransportMissingError | FailToGetOpenIdToken
|
||||
*/
|
||||
@@ -150,9 +154,9 @@ async function makeTransport(
|
||||
membership: CallMembershipIdentityParts,
|
||||
roomId: string,
|
||||
urlFromDevSettings: string | null,
|
||||
matrix2jwt = false,
|
||||
forceOldJwtEndpoint: boolean,
|
||||
delayId?: string,
|
||||
): Promise<LivekitTransportWithVersion> {
|
||||
): Promise<LivekitTransport & { forceOldJwtEndpoint: boolean }> {
|
||||
let transport: LivekitTransport | undefined;
|
||||
logger.trace("Searching for a preferred transport");
|
||||
//TODO refactor this to use the jwt service returned alias.
|
||||
@@ -209,11 +213,12 @@ async function makeTransport(
|
||||
client,
|
||||
membership,
|
||||
transport.livekit_service_url,
|
||||
forceOldJwtEndpoint,
|
||||
transport.livekit_alias,
|
||||
matrix2jwt,
|
||||
client.baseUrl,
|
||||
delayId,
|
||||
logger,
|
||||
);
|
||||
|
||||
return { ...transport, useMatrix2: matrix2jwt };
|
||||
return { ...transport, forceOldJwtEndpoint };
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import fetchMock from "fetch-mock";
|
||||
import EventEmitter from "events";
|
||||
import { type IOpenIDToken } from "matrix-js-sdk";
|
||||
import { logger } from "matrix-js-sdk/lib/logger";
|
||||
import { type LivekitTransport } from "matrix-js-sdk/lib/matrixrtc/LivekitTransport";
|
||||
|
||||
import {
|
||||
Connection,
|
||||
@@ -39,7 +40,6 @@ import {
|
||||
FailToGetOpenIdToken,
|
||||
} from "../../../utils/errors.ts";
|
||||
import { mockRemoteParticipant, ownMemberMock } from "../../../utils/test.ts";
|
||||
import { type LivekitTransportWithVersion } from "./ConnectionManager.ts";
|
||||
|
||||
let testScope: ObservableScope;
|
||||
|
||||
@@ -50,7 +50,7 @@ let fakeLivekitRoom: MockedObject<LivekitRoom>;
|
||||
let localParticipantEventEmiter: EventEmitter;
|
||||
let fakeLocalParticipant: MockedObject<LocalParticipant>;
|
||||
|
||||
const livekitFocus: LivekitTransportWithVersion = {
|
||||
const livekitFocus: LivekitTransport = {
|
||||
livekit_alias: "!roomID:example.org",
|
||||
livekit_service_url: "https://matrix-rtc.example.org/livekit/jwt",
|
||||
type: "livekit",
|
||||
|
||||
@@ -35,8 +35,10 @@ import {
|
||||
} from "../../../utils/errors.ts";
|
||||
|
||||
export interface ConnectionOpts {
|
||||
/** Whether we always try to connect to this connection via the legacy jwt endpoint. (no hash identity) */
|
||||
forceOldJwtEndpoint?: boolean;
|
||||
/** The media transport to connect to. */
|
||||
transport: LivekitTransport & { useMatrix2: boolean };
|
||||
transport: LivekitTransport;
|
||||
/** The Matrix client to use for OpenID and SFU config requests. */
|
||||
client: OpenIDClientParts;
|
||||
/** The observable scope to use for this connection. */
|
||||
@@ -89,7 +91,7 @@ export class Connection {
|
||||
/**
|
||||
* The media transport to connect to.
|
||||
*/
|
||||
public readonly transport: LivekitTransport & { useMatrix2: boolean };
|
||||
public readonly transport: LivekitTransport;
|
||||
|
||||
public readonly livekitRoom: LivekitRoom;
|
||||
|
||||
@@ -192,16 +194,14 @@ export class Connection {
|
||||
this.client,
|
||||
this.ownMembershipIdentity,
|
||||
this.transport.livekit_service_url,
|
||||
this.forceOldJwtEndpoint,
|
||||
this.transport.livekit_alias,
|
||||
this.transport.useMatrix2,
|
||||
// For the remote members we intentionally do not pass a delayEndpointBaseUrl.
|
||||
undefined,
|
||||
// and no delayId.
|
||||
undefined,
|
||||
this.logger,
|
||||
);
|
||||
// client: OpenIDClientParts,
|
||||
// membership: CallMembershipIdentityParts,
|
||||
// serviceUrl: string,
|
||||
// livekitRoomAlias: string,
|
||||
// matrix2jwt: boolean,
|
||||
// delayEndpointBaseUrl?: string,
|
||||
// delayId?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +222,7 @@ export class Connection {
|
||||
|
||||
private readonly client: OpenIDClientParts;
|
||||
private readonly logger: Logger;
|
||||
|
||||
private readonly forceOldJwtEndpoint: boolean;
|
||||
/**
|
||||
* Creates a new connection to a matrix RTC LiveKit backend.
|
||||
*
|
||||
@@ -235,6 +235,7 @@ export class Connection {
|
||||
logger: Logger,
|
||||
private ownMembershipIdentity: CallMembershipIdentityParts,
|
||||
) {
|
||||
this.forceOldJwtEndpoint = opts.forceOldJwtEndpoint ?? false;
|
||||
this.logger = logger.getChild("[Connection]");
|
||||
this.logger.info(
|
||||
`[Connection] Creating new connection to ${opts.transport.livekit_service_url} ${opts.transport.livekit_alias}`,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { type Logger } from "matrix-js-sdk/lib/logger";
|
||||
import E2EEWorker from "livekit-client/e2ee-worker?worker";
|
||||
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
|
||||
import { type LivekitTransport } from "matrix-js-sdk/lib/matrixrtc/LivekitTransport";
|
||||
|
||||
import { type ObservableScope } from "../../ObservableScope.ts";
|
||||
import { Connection } from "./Connection.ts";
|
||||
@@ -23,15 +24,15 @@ import type { MediaDevices } from "../../MediaDevices.ts";
|
||||
import type { Behavior } from "../../Behavior.ts";
|
||||
import type { ProcessorState } from "../../../livekit/TrackProcessorContext.tsx";
|
||||
import { defaultLiveKitOptions } from "../../../livekit/options.ts";
|
||||
import { type LivekitTransportWithVersion } from "./ConnectionManager.ts";
|
||||
|
||||
// TODO evaluate if this should be done like the Publisher Factory
|
||||
export interface ConnectionFactory {
|
||||
createConnection(
|
||||
transport: LivekitTransportWithVersion,
|
||||
transport: LivekitTransport,
|
||||
scope: ObservableScope,
|
||||
logger: Logger,
|
||||
ownMembershipIdentity: CallMembershipIdentityParts,
|
||||
forceOldJwtEndpoint?: boolean,
|
||||
): Connection;
|
||||
}
|
||||
|
||||
@@ -88,10 +89,11 @@ export class ECConnectionFactory implements ConnectionFactory {
|
||||
* @returns
|
||||
*/
|
||||
public createConnection(
|
||||
transport: LivekitTransportWithVersion,
|
||||
transport: LivekitTransport,
|
||||
scope: ObservableScope,
|
||||
logger: Logger,
|
||||
ownMembershipIdentity: CallMembershipIdentityParts,
|
||||
forceOldJwtEndpoint?: boolean,
|
||||
): Connection {
|
||||
return new Connection(
|
||||
{
|
||||
@@ -99,6 +101,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
||||
client: this.client,
|
||||
scope: scope,
|
||||
livekitRoomFactory: this.livekitRoomFactory,
|
||||
forceOldJwtEndpoint,
|
||||
},
|
||||
logger,
|
||||
ownMembershipIdentity,
|
||||
|
||||
@@ -14,29 +14,26 @@ import { logger } from "matrix-js-sdk/lib/logger";
|
||||
import { Epoch, mapEpoch, ObservableScope } from "../../ObservableScope.ts";
|
||||
import {
|
||||
createConnectionManager$,
|
||||
type LivekitTransportWithVersion,
|
||||
type ConnectionManagerData,
|
||||
} from "./ConnectionManager.ts";
|
||||
import { type ConnectionFactory } from "./ConnectionFactory.ts";
|
||||
import { type Connection } from "./Connection.ts";
|
||||
import { ownMemberMock, withTestScheduler } from "../../../utils/test.ts";
|
||||
import { areLivekitTransportsEqual } from "./MatrixLivekitMembers.ts";
|
||||
import { type Behavior } from "../../Behavior.ts";
|
||||
import { constant, type Behavior } from "../../Behavior.ts";
|
||||
|
||||
// Some test constants
|
||||
|
||||
const TRANSPORT_1: LivekitTransportWithVersion = {
|
||||
const TRANSPORT_1: LivekitTransport = {
|
||||
type: "livekit",
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
livekit_alias: "!alias:example.org",
|
||||
useMatrix2: false,
|
||||
};
|
||||
|
||||
const TRANSPORT_2: LivekitTransportWithVersion = {
|
||||
const TRANSPORT_2: LivekitTransport = {
|
||||
type: "livekit",
|
||||
livekit_service_url: "https://lk.sample.com",
|
||||
livekit_alias: "!alias:sample.com",
|
||||
useMatrix2: false,
|
||||
};
|
||||
|
||||
let fakeConnectionFactory: ConnectionFactory;
|
||||
@@ -79,7 +76,8 @@ describe("connections$ stream", () => {
|
||||
const { connectionManagerData$ } = createConnectionManager$({
|
||||
scope: testScope,
|
||||
connectionFactory: fakeConnectionFactory,
|
||||
inputTransports$: behavior("a", {
|
||||
localTransport$: constant(null),
|
||||
remoteTransports$: behavior("a", {
|
||||
a: new Epoch([TRANSPORT_1, TRANSPORT_2], 0),
|
||||
}),
|
||||
logger: logger,
|
||||
@@ -119,7 +117,8 @@ describe("connections$ stream", () => {
|
||||
const { connectionManagerData$ } = createConnectionManager$({
|
||||
scope: testScope,
|
||||
connectionFactory: fakeConnectionFactory,
|
||||
inputTransports$: behavior("abcdef", {
|
||||
localTransport$: constant(null),
|
||||
remoteTransports$: behavior("abcdef", {
|
||||
a: new Epoch([TRANSPORT_1], 0),
|
||||
b: new Epoch([TRANSPORT_1], 1),
|
||||
c: new Epoch([TRANSPORT_1], 2),
|
||||
@@ -165,7 +164,8 @@ describe("connections$ stream", () => {
|
||||
const { connectionManagerData$ } = createConnectionManager$({
|
||||
scope: testScope,
|
||||
connectionFactory: fakeConnectionFactory,
|
||||
inputTransports$: behavior("abc", {
|
||||
localTransport$: constant(null),
|
||||
remoteTransports$: behavior("abc", {
|
||||
a: new Epoch([TRANSPORT_1], 0),
|
||||
b: new Epoch([TRANSPORT_1, TRANSPORT_2], 1),
|
||||
c: new Epoch([TRANSPORT_1], 2),
|
||||
@@ -281,7 +281,8 @@ describe("connectionManagerData$ stream", () => {
|
||||
const { connectionManagerData$ } = createConnectionManager$({
|
||||
scope: testScope,
|
||||
connectionFactory: fakeConnectionFactory,
|
||||
inputTransports$: behavior("a", {
|
||||
localTransport$: constant(null),
|
||||
remoteTransports$: behavior("a", {
|
||||
a: new Epoch([TRANSPORT_1, TRANSPORT_2], 0),
|
||||
}),
|
||||
logger,
|
||||
|
||||
@@ -7,22 +7,18 @@ Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type LivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { combineLatest, map, of, switchMap, tap } from "rxjs";
|
||||
import { combineLatest, map, of, switchMap } from "rxjs";
|
||||
import { type Logger } from "matrix-js-sdk/lib/logger";
|
||||
import { type RemoteParticipant } from "livekit-client";
|
||||
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
|
||||
|
||||
import { type Behavior } from "../../Behavior.ts";
|
||||
import { constant, type Behavior } from "../../Behavior.ts";
|
||||
import { type Connection } from "./Connection.ts";
|
||||
import { Epoch, type ObservableScope } from "../../ObservableScope.ts";
|
||||
import { generateItemsWithEpoch } from "../../../utils/observable.ts";
|
||||
import { areLivekitTransportsEqual } from "./MatrixLivekitMembers.ts";
|
||||
import { type ConnectionFactory } from "./ConnectionFactory.ts";
|
||||
|
||||
export type LivekitTransportWithVersion = LivekitTransport & {
|
||||
useMatrix2: boolean;
|
||||
};
|
||||
|
||||
export class ConnectionManagerData {
|
||||
private readonly store: Map<string, [Connection, RemoteParticipant[]]> =
|
||||
new Map();
|
||||
@@ -64,7 +60,9 @@ export class ConnectionManagerData {
|
||||
interface Props {
|
||||
scope: ObservableScope;
|
||||
connectionFactory: ConnectionFactory;
|
||||
inputTransports$: Behavior<Epoch<LivekitTransportWithVersion[]>>;
|
||||
localTransport$: Behavior<LivekitTransport | null>;
|
||||
remoteTransports$: Behavior<Epoch<LivekitTransport[]>>;
|
||||
forceOldJwtEndpointForLocalTransport$?: Behavior<boolean>;
|
||||
logger: Logger;
|
||||
ownMembershipIdentity: CallMembershipIdentityParts;
|
||||
}
|
||||
@@ -91,13 +89,29 @@ export interface IConnectionManager {
|
||||
export function createConnectionManager$({
|
||||
scope,
|
||||
connectionFactory,
|
||||
inputTransports$,
|
||||
localTransport$,
|
||||
remoteTransports$,
|
||||
forceOldJwtEndpointForLocalTransport$ = constant(false),
|
||||
logger: parentLogger,
|
||||
ownMembershipIdentity,
|
||||
}: Props): IConnectionManager {
|
||||
const logger = parentLogger.getChild("[ConnectionManager]");
|
||||
// TODO logger: only construct one logger from the client and make it compatible via a EC specific sing
|
||||
|
||||
const allInputTransports$ = combineLatest([
|
||||
localTransport$,
|
||||
remoteTransports$,
|
||||
]).pipe(
|
||||
map(([localTransport, transports]) => {
|
||||
const localTransportAsArray = localTransport ? [localTransport] : [];
|
||||
return transports.mapInner((transports) => [
|
||||
...localTransportAsArray,
|
||||
...transports,
|
||||
]);
|
||||
}),
|
||||
map((transports) => transports.mapInner(removeDuplicateTransports)),
|
||||
);
|
||||
|
||||
/**
|
||||
* All transports currently managed by the ConnectionManager.
|
||||
*
|
||||
@@ -106,14 +120,32 @@ export function createConnectionManager$({
|
||||
* It is build based on the list of subscribed transports (`transportsSubscriptions$`).
|
||||
* externally this is modified via `registerTransports()`.
|
||||
*/
|
||||
const transports$ = scope.behavior(
|
||||
inputTransports$.pipe(
|
||||
map((transports) => transports.mapInner(removeDuplicateTransports)),
|
||||
tap(({ value: transports }) => {
|
||||
logger.trace(
|
||||
`Managing transports: ${transports.map((t) => t.livekit_service_url).join(", ")}`,
|
||||
);
|
||||
}),
|
||||
const transportsWithJwtTag$ = scope.behavior(
|
||||
combineLatest([
|
||||
allInputTransports$,
|
||||
localTransport$,
|
||||
forceOldJwtEndpointForLocalTransport$,
|
||||
]).pipe(
|
||||
map(
|
||||
([
|
||||
transports,
|
||||
localTransport,
|
||||
forceOldJwtEndpointForLocalTransport,
|
||||
]) => {
|
||||
// nmodify only the local transport with forceOldJwtEndpointForLocalTransport
|
||||
const index = transports.value.findIndex((t) =>
|
||||
areLivekitTransportsEqual(localTransport, t),
|
||||
);
|
||||
transports.value[index].forceOldJwtEndpoint =
|
||||
forceOldJwtEndpointForLocalTransport;
|
||||
logger.trace(
|
||||
`Managing transports: ${transports.value.map((t) => t.livekit_service_url).join(", ")}`,
|
||||
);
|
||||
return transports as Epoch<
|
||||
(LivekitTransport & { forceOldJwtEndpoint?: boolean })[]
|
||||
>;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -121,7 +153,7 @@ export function createConnectionManager$({
|
||||
* Connections for each transport in use by one or more session members.
|
||||
*/
|
||||
const connections$ = scope.behavior(
|
||||
transports$.pipe(
|
||||
transportsWithJwtTag$.pipe(
|
||||
generateItemsWithEpoch(
|
||||
function* (transports) {
|
||||
for (const transport of transports)
|
||||
@@ -129,23 +161,23 @@ export function createConnectionManager$({
|
||||
keys: [
|
||||
transport.livekit_service_url,
|
||||
transport.livekit_alias,
|
||||
transport.useMatrix2,
|
||||
transport.forceOldJwtEndpoint,
|
||||
],
|
||||
data: undefined,
|
||||
};
|
||||
},
|
||||
(scope, _data$, serviceUrl, alias, useMatrix2) => {
|
||||
(scope, _data$, serviceUrl, alias, forceOldJwtEndpoint) => {
|
||||
logger.debug(`Creating connection to ${serviceUrl} (${alias})`);
|
||||
const connection = connectionFactory.createConnection(
|
||||
{
|
||||
type: "livekit",
|
||||
livekit_service_url: serviceUrl,
|
||||
livekit_alias: alias,
|
||||
useMatrix2,
|
||||
},
|
||||
scope,
|
||||
logger,
|
||||
ownMembershipIdentity,
|
||||
forceOldJwtEndpoint,
|
||||
);
|
||||
// Start the connection immediately
|
||||
// Use connection state to track connection progress
|
||||
|
||||
@@ -13,11 +13,7 @@ import fetchMock from "fetch-mock";
|
||||
import { type LivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { logger } from "matrix-js-sdk/lib/logger";
|
||||
|
||||
import {
|
||||
type Epoch,
|
||||
ObservableScope,
|
||||
trackEpoch,
|
||||
} from "../../ObservableScope.ts";
|
||||
import { type Epoch, ObservableScope, trackEpoch } from "../../ObservableScope.ts";
|
||||
import { ECConnectionFactory } from "./ConnectionFactory.ts";
|
||||
import { type OpenIDClientParts } from "../../../livekit/openIDSFU.ts";
|
||||
import {
|
||||
@@ -34,6 +30,7 @@ import {
|
||||
} from "./MatrixLivekitMembers.ts";
|
||||
import { createConnectionManager$ } from "./ConnectionManager.ts";
|
||||
import { membershipsAndTransports$ } from "../../SessionBehaviors.ts";
|
||||
import { constant } from "../../Behavior.ts";
|
||||
|
||||
// Test the integration of ConnectionManager and MatrixLivekitMerger
|
||||
|
||||
@@ -121,7 +118,8 @@ test("bob, carl, then bob joining no tracks yet", () => {
|
||||
const connectionManager = createConnectionManager$({
|
||||
scope: testScope,
|
||||
connectionFactory: ecConnectionFactory,
|
||||
inputTransports$: membershipsAndTransports.transports$,
|
||||
localTransport$: constant(null),
|
||||
remoteTransports$: membershipsAndTransports.transports$,
|
||||
logger: logger,
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user