Комната отдыха — это обычная функция, необходимая многим клиентам, особенно в сфере образования. Это часто позволяет разделить основную переговорную комнату на отдельные, разделить участников на эти комнаты обсуждения, а также отправить участникам сообщения организатору, независимо от того, в какой комнате они находятся, и т. д.
С Vonage Video API есть несколько способов реализовать такую функцию комнаты отдыха для вашего приложения.
Один из способов — создать большую Видеосессию с логикой, контролирующей, на какие потоки подписаться для каждого пользователя. Другой вариант — внедрить комнаты обсуждения в виде отдельных сеансов, а затем подключить участников к этим различным сеансам, созданным для каждой комнаты обсуждения.
В этом руководстве объясняется, как использовать отдельные сеансы для встраивания функции «Комната обсуждения» в наше демонстрационное приложение, которое использует сигнальный API для реализации управления комнатой обсуждения, повторно использует объект «Издатель» при переключении между комнатами.
Надеюсь, что следующие графики могут дать вам общее представление в первую очередь. Изначально все участники подключаются к сеансу основной комнаты:
После того, как организатор нажимает кнопку для создания комнат обсуждения, сервер приложений вызывает Vonage Video API для создания сеанса для каждой комнаты обсуждения и возвращает эти идентификаторы сеанса каждому участнику.
Затем приложение подключает участников к сеансам этих комнат обсуждения, позволяя участникам выбрать комнату для присоединения или автоматически распределяя участников по разным комнатам, в зависимости от того, какой вариант выбрал организатор при создании комнат обсуждения. (Хозяин может выбрать между «Назначить автоматически» и «Разрешить участникам выбирать комнату»).
Предпосылки
Аккаунт Vonage Video API. Нажмите Зарегистрироваться, чтобы создать его, если у вас его еще нет. Версия ReactJS ›= 16.8 Версия Node.js ›= 16.13 PostgreSQL 14 в качестве базы данных, вы можете выбрать любое хранилище, которое вы предпочитаете
Вы должны увидеть все зависимости в репозитории GitHub, и мы рекомендуем вам всегда использовать последнюю версию Vonage SDK. Перечисленные здесь версии использовались, когда мы работали над этим демо-приложением.
Сервер приложения и дизайн базы данных
Сервер приложений создает комнаты, создает сеансы, генерирует токены, поддерживает комнаты и участников и отправляет сигнальные сообщения в комнаты.
Сервер приложений действует как ретранслятор, используя Signaling-REST API для передачи сообщений между разными комнатами/сеансами для сценариев, когда одному участнику нужно поднять руку на хост, который находится в другой комнате (т.е. подключен к другому сеансу). ), и для основной функции: управление переговорными комнатами. Позже мы подробно объясним, как мы используем сигнальные сообщения в управлении комнатами обсуждения.
При запуске сервера приложений будет создана таблица помещений, если она не существует. Я понимаю, что таблица комнаты может быть немного сложнее в реальной жизни. Здесь мы просто перечислим основные данные, которые нам нужны. Сценарий для создания таблицы комнаты выглядит следующим образом:
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 )
session_id
хранит идентификатор сеанса, связанного с комнатой. max_participants
определяет максимальное количество участников, которое позволяет комната. main_room_id
определяет, является ли это комнатой обсуждения, принадлежащей основной комнате, или просто главной комнатой, в которой могут быть комнаты обсуждения: когда для него установлено значение NULL
, это основная комната; в противном случае это комната обсуждения, и ее значение должно быть равно идентификатору основной комнаты.
Изначально на странице входа все пользователи выбирают присоединиться к одной комнате, также известной как основная комната. После получения внешнего запроса сервер приложений вызывает Video API для создания сеанса для этой основной комнаты и добавляет запись в таблицу комнат с session_id
, установленным на идентификатор созданного сеанса, и main_room_id
, установленным на NULL
. Затем он возвращает session_id
всем зарегистрированным пользователям, чтобы они могли подключиться к сеансу.
Когда собрание продолжается и пользователь-организатор решает создать комнаты обсуждения, после того как он отправит параметры, перечисленные в разделе «Управление комнатой обсуждения», например, сколько комнат обсуждения нужно создать», «Разрешить участникам выбирать комнату» или «Назначить автоматически» и т. д. Front-end отправляет запрос createSession
с параметром breakoutRooms
, содержащим вышеуказанные выборы, на сервер приложений, который затем создаст сеанс для каждой комнаты обсуждения соответственно и сохранит идентификатор сеанса и другую информацию в таблице комнаты, одна запись для каждой комнаты обсуждения с main_room_id
, установленным в качестве идентификатора основной комнаты.
Используйте Signaling API для реализации управления комнатой отдыха
Объект Room содержит ссылки на сеанс, сообщение (breakoutRoomSignal) и участников, а также предоставляет записи для создания комнат обсуждения и управления участниками.
Приложение использует Signaling-REST API для отправки сообщений клиентам, подключенным ко всем сессиям, относящимся к основной комнате/комнате отдыха, информированию об изменениях комнаты, запросам таймера и поднятия руки и т. д.
Например, сигнальное сообщение с указанным ниже типом и данными предназначено для информирования пользователей приложения о создании новых комнат обсуждения, и они могут выбрать одну из них для присоединения:
{ "type": "signal:breakout-room", "data": { "message": "roomCreated (chooseroom)", "breakoutRooms": \[], //array of available rooms } }
- сигнальное сообщение об удалении всех комнат:
{ "type": "signal:breakout-room", "data": { "message": "allRoomRemoved", "breakoutRooms": \[...], } }
- сообщить участнику, который перемещается из одной (сессионной) комнаты в другую:
{ "type": "signal:breakout-room", "data": { "message": "'participantMoved'", "breakoutRooms": \[...], } }
- в то время как сигнальное сообщение с типом, установленным на
signal:count-down-timer
, должно информировать о таймере:
{ "type": "signal:count-down-timer", "data": { "period": 1, } }
Для этих breakoutRoomSignal
сообщений приложение выполняет соответствующие действия, например, для participantMoved
оно перемещает участника в назначенную комнату.
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)) }
В течение handleChangeRoom
приложение покинет текущую комнату (путем отключения от связанного сеанса) и присоединится к назначенной комнате (путем подключения к связанному сеансу).
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); }
Повторно используйте объект Publisher при переключении между комнатами
Когда участник покидает основную комнату и присоединяется к комнате обсуждения (или иным образом), рекомендуется повторно использовать объект Publisher для экономии ресурсов.
Для каждого type": "signal:breakout-room
сообщения, которое может заставить клиента выйти из комнаты и присоединиться к другой комнате, например. roomCreated (automatic)
приложение отключается от сеанса, а затем подключается к другому сеансу. При этом поток, опубликованный в предыдущей сессии, будет уничтожен, а клиенту публикатора будет отправлено событие streamDestroyed. Чтобы сохранить объект Publisher для повторного использования, следует вызвать метод preventDefault события streamDestroyed.
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 }) } }
Демонстрационное приложение повторно использует этот объект Publisher для публикации в сеансе, связанном с комнатой обсуждения.
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); } }
Заключение
Используя способ создания отдельных сеансов для функции комнаты обсуждения, вам нужно беспокоиться только о подключении участников к нужному сеансу. Взгляните на код для получения более подробной информации, и, надеюсь, вы найдете это полезным для вашего приложения для комнаты отдыха.