feat: implement remote homeserver handling for LiveKit calls
This commit is contained in:
@@ -1,6 +1,59 @@
|
||||
import { useCallback } from 'react';
|
||||
import { Room } from 'matrix-js-sdk';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { LiveKitFocus, LiveKitJWTResponse, OpenIdToken, WellKnownWithRTC } from './types';
|
||||
import { getMxIdServer } from '../../utils/matrix';
|
||||
import { guessDmRoomUserId } from '../../utils/matrix';
|
||||
|
||||
/**
|
||||
* Get room server from room ID (format: !roomid:server.com)
|
||||
*/
|
||||
function getRoomServer(roomId: string): string | undefined {
|
||||
return getMxIdServer(roomId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which homeservers to try for LiveKit JWT, in priority order
|
||||
* @param room - Room to start call in
|
||||
* @param userHomeserver - User's homeserver
|
||||
* @param myUserId - Current user's Matrix ID
|
||||
* @returns Array of homeserver base URLs to try in order
|
||||
*/
|
||||
export function getLiveKitHomeserverPriority(
|
||||
room: Room,
|
||||
userHomeserver: string,
|
||||
myUserId: string
|
||||
): string[] {
|
||||
const servers: string[] = [];
|
||||
const memberCount = room.getMembers().length;
|
||||
const isDM = memberCount <= 2;
|
||||
|
||||
if (isDM) {
|
||||
// For DMs: user's homeserver first, then other member's homeserver
|
||||
servers.push(userHomeserver);
|
||||
|
||||
const otherUserId = guessDmRoomUserId(room, myUserId);
|
||||
if (otherUserId && otherUserId !== myUserId) {
|
||||
const otherServer = getMxIdServer(otherUserId);
|
||||
if (otherServer && otherServer !== userHomeserver) {
|
||||
servers.push(`https://${otherServer}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For channels: room's homeserver first, then user's homeserver
|
||||
const roomServer = getRoomServer(room.roomId);
|
||||
if (roomServer) {
|
||||
servers.push(`https://${roomServer}`);
|
||||
}
|
||||
|
||||
// Fallback to user's homeserver if different
|
||||
if (!roomServer || roomServer !== userHomeserver.replace('https://', '').replace('http://', '')) {
|
||||
servers.push(userHomeserver);
|
||||
}
|
||||
}
|
||||
|
||||
return servers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the LiveKit focus configuration from well-known data
|
||||
@@ -113,6 +166,59 @@ export async function fetchLiveKitJWT(
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try fetching LiveKit JWT from multiple homeservers in priority order
|
||||
* @param homeservers - Array of homeserver base URLs to try
|
||||
* @param roomId - The Matrix room ID
|
||||
* @param userId - The Matrix user ID
|
||||
* @param deviceId - The Matrix device ID
|
||||
* @param accessToken - The Matrix access token
|
||||
* @returns LiveKit JWT response and the homeserver that provided it, or null
|
||||
*/
|
||||
export async function fetchLiveKitJWTFromServers(
|
||||
homeservers: string[],
|
||||
roomId: string,
|
||||
userId: string,
|
||||
deviceId: string,
|
||||
accessToken: string
|
||||
): Promise<{ jwt: LiveKitJWTResponse; homeserver: string } | null> {
|
||||
for (const homeserver of homeservers) {
|
||||
try {
|
||||
console.log(`Trying LiveKit JWT from homeserver: ${homeserver}`);
|
||||
|
||||
// Fetch well-known from this homeserver
|
||||
const wellKnown = await fetchWellKnownWithRTC(homeserver);
|
||||
const livekitFocus = getLiveKitFocus(wellKnown);
|
||||
|
||||
if (!livekitFocus) {
|
||||
console.log(`No LiveKit config on ${homeserver}, trying next...`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get OpenID token from this homeserver
|
||||
const openIdToken = await requestOpenIdToken(homeserver, userId, accessToken);
|
||||
|
||||
// Exchange for LiveKit JWT
|
||||
const jwt = await fetchLiveKitJWT(
|
||||
livekitFocus.livekit_service_url,
|
||||
roomId,
|
||||
userId,
|
||||
deviceId,
|
||||
openIdToken
|
||||
);
|
||||
|
||||
console.log(`Successfully got LiveKit JWT from ${homeserver}`);
|
||||
return { jwt, homeserver };
|
||||
} catch (error) {
|
||||
console.warn(`Failed to get LiveKit JWT from ${homeserver}:`, error);
|
||||
// Continue to next homeserver
|
||||
}
|
||||
}
|
||||
|
||||
console.error('Failed to get LiveKit JWT from any homeserver');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get RTC configuration functions
|
||||
* Provides utilities for fetching well-known data and LiveKit JWTs
|
||||
|
||||
Reference in New Issue
Block a user