
Partager:
Iu Jie is a Software Engineer who is constantly seeking innovative ways to solve a problem. She is passionate about new technology, especially relating to cloud and AI. Out of work, she likes to spend her time hunting for tasty food with family.
Créez une application de salle de réunion en JavaScript avec l'API Video de Vonage
Temps de lecture : 6 minutes
Cet article a été rédigé en collaboration avec Yinping Ge
La salle de réunion est une fonction couramment demandée par de nombreux clients, en particulier dans le secteur de l'éducation. Elle permet souvent de "diviser la salle de réunion principale en plusieurs salles distinctes", de "répartir les participants dans ces salles" et de "permettre aux participants d'envoyer des messages à l'hôte quelle que soit la salle dans laquelle ils se trouvent", etc.
Avec Vonage Video APIde Vonage, il y a plus d'une façon de mettre en œuvre une telle fonction de salle de réunion pour votre application.
L'une des solutions consiste à créer une grande Session Video avec une logique contrôlant les flux auxquels s'abonner pour chaque utilisateur. Une autre solution consiste à "mettre en place des salles de réunion en tant que sessions distinctes", puis à "connecter les participants à ces différentes sessions créées pour chaque salle de réunion".
Ce tutoriel explique comment utiliser la fonction sessions séparées pour intégrer la fonction de salle de réunion dans notre Applications de démonstration, qui utilise l'API de signalisation pour mettre en œuvre la gestion des salles de réunion réutilise l'objet Publisher pour passer d'une salle à l'autre.
J'espère que les graphiques suivants vous donneront une première idée générale. Au départ, tous les participants se connectent à la session de la salle principale :

Une fois que l'hôte a cliqué sur le bouton pour créer des salles de réunion, le serveur d'application appelle l'API Video de Vonage pour créer une session pour chaque salle de réunion et renvoie ces identifiants de session à chaque participant.

L'application connecte ensuite les participants aux sessions de ces salles en les laissant choisir une salle ou en les répartissant automatiquement dans différentes salles, en fonction de l'option sélectionnée par l'hôte lors de la création des salles (l'hôte peut choisir entre "Attribuer automatiquement" et "Laisser les participants choisir une salle").
Conditions préalables
Un compte Video API de Vonage. Cliquez sur S'inscrire pour en créer un si vous n'en avez pas déjà un. ReactJS version >= 16.8 Node.js version >= 16.13 PostgreSQL 14 comme base de données, vous pouvez choisir n'importe quel stockage que vous préférez.
Vous devriez être en mesure de voir toutes les dépendances dans le GitHub repo et nous vous suggérons de toujours utiliser la dernière version de Vonage SDK. Les versions listées ici sont celles qui ont été utilisées lorsque nous avons travaillé sur cette application de démonstration.
Conception du serveur et de la base de données de l'Applications
Le serveur d'application crée des salles, crée des sessions, génère des jetons, gère les salles et les participants et envoie des messages de signalisation aux salles.
Le serveur d'application fait office de "relais" en utilisant l'API Signaling-REST API pour transmettre des messages entre différentes salles/sessions, par exemple lorsqu'un participant doit lever la main sur l'animateur qui se trouve dans une autre salle (c'est-à-dire connecté à une autre session), et pour la fonction principale : la gestion des salles de réunion. Nous expliquerons plus loin en détail comment nous utilisons les messages de signalisation pour gérer les salles de réunion.
Lors de l'exécution du serveur d'application, la table de salle sera créée si elle n'existe pas. Je comprends que la table de chambre puisse être un peu plus complexe dans la réalité. Ici, nous nous contentons d'énumérer les données de base dont nous avons besoin. Le script pour créer la table des chambres est le suivant :
CREATE TABLE IF NOT EXISTS rooms(
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) DEFAULT NULL,
session_id VARCHAR(255) DEFAULT NULL,
main_room_id VARCHAR(255) DEFAULT NULL,
max_participants SMALLINT DEFAULT 0
)L'identifiant session_id stocke l'identifiant d'une session associée à la salle. Le max_participants définit le nombre maximum de participants que la salle peut accueillir. L'option main_room_id permet de différencier s'il s'agit d'une salle de réunion qui appartient à la salle principale ou simplement d'une salle principale qui peut avoir des salles de réunion : lorsqu'il a pour valeur NULLil s'agit d'une salle principale ; dans le cas contraire, il s'agit d'une salle de réunion et sa valeur doit correspondre à l'identifiant de la salle principale.
Au départ, sur la page de connexion, tous les utilisateurs choisissent de rejoindre une salle, la salle principale. Lorsqu'il reçoit la demande du front-end, le serveur d'application appelle Video API pour créer une session pour cette salle principale et ajoute un enregistrement à la table de la salle avec session_id l'identifiant de la session créée et main_room_id défini à NULL. Il renvoie ensuite l'enregistrement session_id à tous les utilisateurs connectés pour qu'ils se connectent à la session.
Lorsque la réunion est en cours et qu'un utilisateur hôte décide de créer des salles de réunion, il soumet les options énumérées dans "Contrôle des salles de réunion", telles que le nombre de salles de réunion à créer, "Laisser les participants choisir la salle", ou "Attribuer automatiquement", etc. Le front-end envoie une createSession avec le paramètre breakoutRooms contenant les sélections ci-dessus au serveur d'application, qui créera alors une session pour chaque salle de réunion en conséquence et stockera l'identifiant de la session et d'autres informations dans la table de la salle, un enregistrement pour chaque salle de réunion avec le paramètre main_room_id à l'identifiant de la salle principale.
Utiliser l'API de signalisation pour mettre en œuvre la gestion des salles de pause
L'objet Room contient les références à la session, au message (breakoutRoomSignal) et aux participants et fournit les entrées pour la création de salles de réunion et la gestion des participants.
L'application utilise l'API Signaling-REST pour envoyer des messages aux clients connectés à toutes les sessions liées à une salle principale/une salle de repos, les informant des changements de salle, des demandes de minuterie et de main levée, etc.
Par exemple, le message de signalisation avec le type et les données ci-dessous sert à informer les utilisateurs de l'application de la création de nouvelles salles de réunion et du fait qu'ils peuvent choisir d'en rejoindre une :
{
"type": "signal:breakout-room",
"data": {
"message": "roomCreated (chooseroom)",
"breakoutRooms": \[], //array of available rooms
}
}message de signalisation pour informer que "toutes les chambres ont été supprimées" :
{
"type": "signal:breakout-room",
"data": {
"message": "allRoomRemoved",
"breakoutRooms": \[...],
}
}informer un participant qui est déplacé d'une salle (de réunion) à une autre :
{
"type": "signal:breakout-room",
"data": {
"message": "'participantMoved'",
"breakoutRooms": \[...],
}
}tandis qu'un message de signalisation dont le type est défini à
signal:count-down-timerest destiné à informer de l'existence d'une minuterie :
{
"type": "signal:count-down-timer",
"data": {
"period": 1,
}
}Pour ces breakoutRoomSignal messages, l'application prend des mesures en conséquence, par exemple pour participantMovedl'application déplace le participant dans la salle qui lui a été attribuée.
if (mMessage.breakoutRoomSignal.message === 'participantMoved' && roomAssigned && (!currentRoomAssigned || currentRoomAssigned.id !== roomAssigned.id)) {
setCurrentRoomAssigned(roomAssigned);
mNotification.openNotification("Room assigned by Host/Co-host", `You will be redirected to Room: ${roomAssigned.name} in 5 seconds.`, () => handleChangeRoom(roomAssigned.name))
}
À l'intérieur de handleChangeRooml'application quittera la salle actuelle (en se déconnectant de sa session associée) et rejoindra la salle assignée (en se connectant à sa session associée).
async function handleChangeRoom(publisher, roomName) {
const newRooms = \ [...mMessage.breakoutRooms];
let targetRoom = newRooms.find((room) => room.name === roomName);
await mSession.session.unpublish(publisher);
await mSession.session.disconnect();
const connectionSuccess = await connect(mSession.user, targetRoom ? targetRoom.id : '');
if (!connectionSuccess) {
// Force connect to main room;
targetRoom = null;
roomName = '';
await connect(mSession.user);
}
let data = {
fromRoom: currentRoom.name,
toRoom: roomName ? roomName : mainRoom.name,
participant: mSession.user.name
}
setInBreakoutRoom(targetRoom && targetRoom.name !== mainRoom.name ? targetRoom : null);
}
Réutiliser l'objet de l'éditeur lorsque l'on passe d'une pièce à l'autre
Lorsqu'un participant quitte la salle principale et rejoint une salle de réunion (ou autre), il est recommandé de réutiliser l'objet Publisher afin d'économiser des ressources.
Pour chaque type": "signal:breakout-room qui peut amener un client à quitter une salle et à en rejoindre une autre, par exemple, l'application se déconnecte d'une session et se connecte à une autre session. roomCreated (automatic)l'application se déconnecte d'une session et se connecte à une autre session. Au cours de ce processus, le flux publié pour la session précédente sera détruit et l'événement streamDestroyed sera envoyé au client de l'éditeur. Afin de conserver l'objet Publisher pour le réutiliser, la méthode preventDefault de l'événement streamDestroyed doit être appelée.
function handleStreamDestroyed(e) {
if (e.stream.name !== "sharescreen") e.preventDefault();
if (e.reason === 'forceUnpublished') {
console.log('You are forceUnpublished');
setStream({
...e.stream
})
setPublisher({
...e.stream.publisher
})
}
}L'application de démonstration réutilise cet objet Publisher pour publier dans la session associée à la salle de réunion.
async function publish(
user,
extraData
) {
try {
if (!mSession.session) throw new Error("You are not connected to session");
if (!publisher || publisherOptions.publishVideo !== hasVideo || publisherOptions.publishAudio !== hasAudio) {
if (publisher) resetPublisher();
const isScreenShare = extraData && extraData.videoSource === 'screen' ? true : false;
const options = {
insertMode: "append",
name: user.name,
publishAudio: isScreenShare ? true : hasVideo,
publishVideo: isScreenShare ? true : hasAudio,
style: {
buttonDisplayMode: "off",
nameDisplayMode: displayName ? "on" : "off"
}
};
const finalOptions = Object.assign({}, options, extraData);
setPublisherOptions(finalOptions);
const newPublisher = OT.initPublisher(containerId, finalOptions);
publishAttempt(newPublisher, 1, isScreenShare);
} else {
publishAttempt(publisher);
}
} catch (err) {
console.log(err.stack);
}
}
Conclusion
Grâce à la possibilité de créer des sessions distinctes pour la fonction de salle de réunion, vous n'avez plus qu'à vous soucier de connecter les participants à la bonne session. Jetez un coup d'œil au le code pour plus de détails et nous espérons que vous trouverez cela utile pour votre application de salle de réunion.