Salles de sous-groupe
Salles de sous-groupe (breakout rooms)
Ce que ça fait
Répartit les participants d’une salle en plusieurs sous-salles, avec un jeton d’accès par participant — sans dépendre d’une fonctionnalité serveur qui n’existe que sur LiveKit Cloud (voir « Pièges »).
Ce que Legba fait, ce que l’application fait
Legba planifie (planBreakoutRooms) et provisionne (createBreakoutRooms) : il crée les sous-salles et émet un jeton par participant. Le reste — livrer ce jeton au bon navigateur, et faire basculer une connexion d’une salle à l’autre — reste du côté de l’application, avec les briques déjà fournies par @legba-core/realtime.
Étape 1 — Répartir et provisionner (backend)
import { createRoomService, planBreakoutRooms, createBreakoutRooms } from "@legba-core/realtime";
const rooms = createRoomService({ serverUrl, apiKey, apiSecret });
const plan = planBreakoutRooms(participantIdentities, {
groupSize: 5,
roomNamePrefix: "salle-groupe",
mode: "random", // ou "sequential" pour préserver l'ordre fourni
});
const { tokensByIdentity } = await createBreakoutRooms(rooms, plan, {
apiKey,
apiSecret,
role: "participant",
});
Pour une répartition décidée à la main (le modérateur choisit qui va où dans son interface), construire directement la liste d’assignations et sauter planBreakoutRooms :
const manualPlan = [
{ roomName: "salle-groupe-vip", participantIdentities: ["alice"] },
{ roomName: "salle-groupe-debutants", participantIdentities: ["bob", "carol"] },
];
const { tokensByIdentity } = await createBreakoutRooms(rooms, manualPlan, { apiKey, apiSecret, role: "participant" });
Étape 2 — Livrer le jeton (application)
Comment transmettre tokensByIdentity[identity] au bon navigateur est un choix d’architecture propre à chaque application — un canal de données (sendData, LGB-015) vers ce participant précis, une réponse HTTP, un WebSocket applicatif, etc. Legba ne l’impose pas.
Étape 3 — Basculer de salle (navigateur)
Chaque client (modérateur compris) reçoit son jeton et fait un disconnect() suivi d’un connect() — les mêmes méthodes que LGB-013, rien de nouveau :
// room : instance LegbaClientRoom déjà connectée à la salle principale
await room.disconnect();
await room.connect({ serverUrl, token: tokenPourCetteSousSalle });
Observer une sous-salle sans la quitter
Un modérateur qui veut surveiller une sous-salle sans quitter la salle principale ouvre simplement une deuxième instance LegbaClientRoom :
const salleMoniteur = createLegbaRoom();
await salleMoniteur.connect({ serverUrl, token: tokenObservateur });
// room (première instance) reste connectée à la salle principale pendant ce temps
Pièges
moveParticipant/forwardParticipantdu SDK LiveKit ne fonctionnent jamais en self-hosted — vérifié contre un vrai serveurlivekit-server:twirp error unknown: not implemented. Confirmé par l’équipe LiveKit elle-même : ces RPC nécessitent un routage entre nœuds qui n’existe que sur LiveKit Cloud. C’est pour ça que cette recette provisionne des jetons plutôt que d’encaspuler ces méthodes.createBreakoutRoomsest idempotent sur la création des salles (une salle de destination déjà existante n’est pas une erreur), mais rejette une répartition manuelle incohérente (une identité assignée à deux salles, une salle sans participant) avant tout appel réseau.- Le
disconnect()/connect()côté client entraîne une brève coupure de connexion (perceptible mais très courte) — ce n’est pas un changement de salle invisible comme le serait un vraimoveParticipantcôté serveur. - Livrer les jetons reste hors du périmètre de Legba : choisir un canal de livraison qui n’expose jamais un jeton à un participant autre que celui pour qui il a été émis.