В основе системы видео-конференц-связи в наших продуктах Squadus и Squadus PRO лежит open-source решение Jitsi. Однако нам пришлось существенно его доработать – у базовой Jitsi есть ограничения, которые не позволяют выстроить надёжную корпоративную ВКС под бизнес-цели.
Рассказываем, как мы адаптировали решение с минимальным вмешательством в код, разобрались с масштабируемостью и интеграцией с другими нашими сервисами и создали безопасную и стабильную систему с гибким управлением правами.
Под катом разберем наш путь — от адаптации Jitsi «из коробки» до разработки функций для вебинаров и конференций. Также рассмотрим методы улучшения функциональности с помощью Prosody-плагинов, особенности масштабирования, создание мультиконференций, управление правами доступа и технические доработки, которые могут быть полезны разработчикам, работающим над подобными задачами.
Привет, Хабр! С вами Андрей Сапронов и Леонид Леонтьев из департамента разработки цифрового рабочего пространства Squadus в МойОфис.
Полтора года назад мы выпустили Squadus — приложение для корпоративного общения, конференций, совместной работы над документами, с возможностью автоматизации типовых действий с помощью ботов. А недавно представили Squadus PRO — расширенную версию продукта, в котором также доступны встроенные веб-редакторы документов и файловое хранилище.
О нюансах разработки Squadus уже рассказали на Хабре наши коллеги: в статьях про бэкенд, фронтенд, UX решения и функциональность мобильной версии. Мы же сосредоточимся на теме ВКС и расскажем, как расширить возможности системы корпоративной видео-конференц-связи на примере нашего продукта.
Архитектурные подходы к построению ВКС
У ВКС-систем могут быть разные архитектуры со своими сильными и слабыми сторонами. Давайте разберем их подробнее:
MESH-архитектура (одноранговая сеть): каждый участник отправляет свой медиапоток всем остальным — это снижает стоимость инфраструктуры. У подхода есть ограничения по числу участников из-за нагрузки на сеть и устройства: с увеличением количества участников нагрузка растёт экспоненциально — это делает его непригодным для масштабируемых решений.
MCU-архитектура (Multipoint Control Unit): медиапотоки обрабатываются на центральном сервере, который микширует их и отправляет единый поток всем участникам. Это снижает нагрузку на клиентские устройства, но требует мощных серверов и большого количества ресурсов для обработки и кодирования медиа.
SFU-архитектура (Selective Forwarding Unit): медиапотоки передаются через сервер без обработки, что обеспечивает хорошую масштабируемость. SFU передаёт только те потоки, которые подходят по пропускной способности сети клиента. Этот подход даёт оптимальный баланс между нагрузкой на клиенты и сервер.
Для создания нашей ВКС мы выбрали open-source систему Jitsi с SFU-архитектурой. Это зрелая и проверенная система, которую применяют для гибридных решений, где важна масштабируемость и производительность. Jitsi встроена во многие российские мессенджеры, а значительное число популярных отечественных ВКС-систем используют её как базу.
Однако в базовом виде у Jitsi есть ограничения, так как она не предоставляет расширенных функций для корпоративной среды. Именно поэтому мы создали обёртку вокруг Jitsi, которая глубоко интегрирует её в чат-систему Squadus, обеспечивая целостное решение для корпоративной ВКС. Рассказываем подробнее, как мы доработали систему.
Расширенные возможности управления встречами
В Jitsi нет системы управления встречами — она ограничена созданием ссылок и минимальными настройками, а каждая конференция воспринимается как отдельная сессия. В корпоративных условиях этого недостаточно: нужно заранее назначать организаторов, устанавливать права, сохранять записи для отчётности, передавать в видеоконференцию персональные настройки камеры и микрофона для каждого пользователя. Кроме того, нужно заранее задавать пароль и включать комнату ожидания для проверки участников перед началом встречи.
Для решения этих задач мы разработали дополнительные сервисы, обеспечивающие управление встречами, запись и хранение данных, повторное использование ссылок и другие функции.
Сервис управления конференциями (CCS — conference control service) — это один из ключевых элементов, позволяющий заранее создавать ссылки на встречи, назначать организаторов и модераторов, приглашать пользователей и уведомлять их о предстоящих встречах через звонки или push-уведомления. Более того, CCS сохраняет права доступа пользователей к материалам по прошедшим встречами. Например, после завершения конференции сохраняются записи и чат, которые можно привязать к конкретной встрече, что делает систему удобной для анализа и использования данных.
Как мы реализовали CCS:
Обработка событий через Prosody-плагины. Lua-плагины помогают отследить изменения прав участников видеоконференции и события входа/выхода. Эти данные передаются в CCS, где сохраняются для дальнейшего использования.
Интеграция с REST API. CCS может взаимодействовать с другими корпоративными системами через REST API, например, CRM или системы хранения данных. Это упрощает интеграцию ВКС в другие сервисы компании, такие, как почта.
Prosody — это легковесный и высокопроизводительный XMPP-сервер (Extensible Messaging and Presence Protocol), который используется для обмена сообщениями и управления статусами пользователей. Он написан на языке Lua, что делает его быстрым и легко расширяемым с помощью плагинов. В Jitsi Prosody играет ключевую роль в обеспечении сигнальных функций, необходимых для организации видеоконференций.
Вот функции, которые Prosody выполняет в Jitsi:
Используется для идентификации и аутентификации участников. Это позволяет гибко настраивать доступ к конференциям, в том числе поддерживать корпоративные схемы авторизации, такие как LDAP или JWT токены.
Обрабатывает запросы на вход и выход участников в конференцию, поддерживает их статус (например, подключен ли микрофон, видео), а также синхронизирует эти данные между всеми пользователями.
С ним администраторы могут задавать различные роли участникам, назначая их модераторами или простыми участниками. Эта функция используется для корпоративных встреч, где требуется четкое разделение ролей и прав.
Поддерживает плагины на Lua, что позволяет добавлять новые функции, не изменяя исходный код. В Jitsi это может быть полезно для таких функций, как запись конференций, поддержка субтитров, интеграция с внешними API и управление встречами.
Управляет сигналингом, то есть отправкой сообщений, которые координируют действия участников (например, включение или отключение видео), и обменом различной служебной информацией, необходимой для синхронизации данных между пользователями.
Prosody-плагины стали одним из ключевых элементов интеграции нашей системы. Они играют роль прослойки для обработки и передачи событий. Схема работы такая: в нашей архитектуре есть клиентское приложение Squadus, сервис управления конференциями (CCS) и сервер Prosody с плагинами. Когда в Jitsi происходит какое-то событие, плагины на Prosody перехватывают его, обрабатывают и отправляют данные в CCS (наше внутреннее название — Scandium). Последний, в свою очередь, сохраняет информацию, проверяет права доступа и выполняет более сложную логику, полностью контролируя работу с конференциями. Например, если пользователь пишет сообщение в чат, это событие перехватывается плагином, обрабатывается и пересылается в CCS для дальнейшего использования.
Squadus в этой схеме является клиентом, но его можно заменить на любое другое приложение. Такой подход обеспечивает гибкость, но требует детальной настройки и тестирования для корректной работы всех компонентов.
Одна из сложностей, с которой мы столкнулись — необходимость адаптировать систему под обновления Jitsi, сохраняя работоспособность плагинов. Мы пишем код на Lua, используя XMPP-протокол для общения между компонентами, и делаем все, чтобы плагин был независим от изменений в Jitsi. Этот процесс требует знания структуры событий и умения настраивать логику плагина, которая остаётся простой для поддержки.
В целом, плагины в Prosody работают по схожему принципу: мы подписываемся на нужное событие, обрабатываем его и передаем в CCS, который выполняет более сложные задачи, такие как управление правами и хранение данных. Prosody в этом случае выступает в качестве облегчённой прослойки, которая передаёт базовую информацию для дальнейшей обработки в CCS, оставляя сложную логику на стороне полноценного сервиса управления.
Как мы расширили возможности управления встречами — коротко:
1. Предварительное планирование встреч: CCS позволяет создавать ссылки заранее и отправлять приглашения, назначать организаторов и модераторов.
2. Сохранение материалов и субтитров: система записывает встречу и сохраняет её, включая чат и документы, что позволяет пользователям возвращаться к обсуждению позже.
3. Prosody-плагины для записи чатов: мы создали плагины на Lua, которые перехватывают события сообщений, отправляют их в отдельное хранилище и сохраняют сообщения в виде истории чатов.
4. Интеграция с сервером управления встречами: настройка системы управления, которая будет сохранять материалы, записи и документы. Может быть полезна для крупных компаний, где важен доступ к истории переписок.
Управление правами доступа
Корпоративные решения требуют гибкой системы управления правами доступа, особенно для повторных встреч. В Jitsi нет встроенной системы ролей, что сильно ограничивает ее в корпоративном использовании.
Как мы реализовали систему прав:
Создание ролей и прав: можно использовать сервер управления встречами для создания ролей организатора, модератора, участника и наблюдателя, а также для управления доступом к чатам, документам и записям.
Интеграция с системой аутентификации: например, с LDAP или SSO. Это помогает легко управлять пользователями и правами доступа в ВКС.
В системе управления конференциями (CCS) при создании JWT-токена для пользователя мы включаем в него дополнительную служебную информацию, специфичную для предстоящей конференции или вебинара. Такой подход позволяет гибко управлять параметрами доступа и настраивать интерфейс под каждого участника. Например, в токен добавляется информация о роли пользователя в конференции — это может быть статус спикера, модератора или слушателя. Благодаря этому система сразу назначает нужные права и уровень доступа при подключении.
Еще одно дополнение — информация о предпочитаемом языке интерфейса. CCS передаёт этот параметр в Jitsi, чтобы интерфейс видеоконференции в Squadus автоматически отобразился на нужном языке, согласованном с настройками пользователя. Такой подход упрощает взаимодействие с ВКС и делает его более удобным для пользователей.
Поддержка субтитров и транскрибации через Prosody-плагины
Запись субтитров — ещё одна возможность, отсутствующая в Jitsi «из коробки». Хотя базовая версия и предлагает субтитры, на практике они работают только в реальном времени и не сохраняются. Чтобы реализовать их полноценное сохранение, мы доработали бэкенд Jitsi, используя тот же XMPP-сервер Prosody. Наша система перехватывает события конференции, обрабатывает их и сохраняет субтитры вместе с другими материалами встречи.
Как мы это реализовали:
Создание Prosody-плагинов: плагины на Lua отслеживают события (например, начало/окончание речи) и отправляют данные в сервер управления для сохранения.
Использование сервисов распознавания речи: для распознавания речи можно интегрировать сторонние API, такие как Whisper, Google Speech или VOSK, которые позволят получать транскрипции и сохранять их вместе с записью звонка.
Мы работаем над улучшением распознавания речи для автоматического создания выжимок обсуждений — это облегчает анализ и подведение итогов встреч. В данный момент мы используем систему VOSK для распознавания речи.
Она справляется с повседневными фразами, но может ошибаться при работе с техническими терминами. Для повышения качества распознавания и точности записи мы внедряем этап постобработки. Сейчас мы тестируем его возможности, и пока не добавляли его в релизы. Постобработка позволит просматривать полную и исправленную расшифровку встречи. Функция будет полезна для отчётов и документирования сложных технических обсуждений.
Масштабирование для вебинаров и крупных трансляций
Вебинары — один из сложных моментов при адаптации Jitsi для корпоративного использования. Основное узкое место системы — сервер Prosody, который начинает тормозить, если количество участников одной конференции превышает 500 человек. Это происходит потому, что каждый новый пользователь вынужден обмениваться статусами со всеми уже подключенными участниками. Когда к конференции подключается 500-й человек, его статус должен быть разослан остальным 499 пользователям, и это создаёт значительную нагрузку на сервер.
Для решения этой проблемы существует концепция распределённой архитектуры для вебинаров. Участников можно разделить на группы «выступающих» и «слушателей». Выступающие — ограниченное число людей с активными камерами и микрофонами, обычно это спикеры или модераторы. Слушатели, в свою очередь подключенные к другим экземплярам Prosody, не обмениваются статусами включения и выключения камеры и микрофона, не знают имен и аватаров друг друга и поэтому не создают большой нагрузки. С таким подходом каждый экземпляр Prosody может поддерживать до 1500 пользователей. Развернув несколько таких серверов, мы смогли обеспечить поддержку вебинаров на 1000 участников. В теории, возможности позволяют довести число участников до 10 000.
Еще один недостаток Jitsi: при проведении вебинаров система присваивает привилегии спикера первым подключившимся к конференции, что не подходит для управления реальными мероприятиями. Мы вместе со специалистами Jitsi решили эту проблему. За основу мы взяли экспериментальную версию реализации вебинаров: добавили в Squadus веб-интерфейс, который позволяет назначить права участников заранее с использованием токенов JWT. Это позволило определить, у кого именно есть права спикера или модератора, и предотвратило путаницу с привилегиями.
Как уже упоминалось выше, мы стараемся минимально вмешиваться в код Jitsi, добавляя функции через собственные плагины и надстройки. Это даёт возможность быстро обновлять Jitsi и интегрировать новые возможности без конфликтов. Такие доработки делают систему более гибкой и подходящей для корпоративных нужд, превращая ее в полноценное решение для масштабных вебинаров и других мероприятий.
Как мы улучшили масштабирование — коротко:
Разделение ролей. Для вебинаров разделили участников на две группы: выступающие и слушатели. Это минимизирует нагрузку на сервер, так как слушатели получают только основные медиапотоки и не обмениваются статусными сообщениями, например, о включении/выключении микрофона.
Распределённая архитектура. Настроили несколько экземпляров Prosody для работы с группами слушателей. Пулы для участников синхронизируются с основным сервером выступающих по ключевым событиям. Это позволяет поддерживать до нескольких тысяч участников.
Какие еще функции мы добавили
Интерактивная белая доска для совместной работы
Интерактивные инструменты, такие как белая доска, помогают визуализировать идеи и обсуждать задачи в реальном времени, особенно при мозговых штурмах.
Как добавить белую доску:
Доску можно подключить в виде отдельного приложения на JavaScript и встроить её в интерфейс Jitsi с помощью iframe. Важно предусмотреть сохранение всех данных на сервере, чтобы участники могли к ним возвращаться после завершения встречи. Для белой доски лучше всего подходит обмен данными через WebSocket, так как это позволяет минимизировать задержки.
Участие в нескольких конференциях
Многие пользователи сталкиваются с ситуацией, когда нужно присутствовать сразу на нескольких встречах. В базовой версии Jitsi одновременно участвовать в нескольких звонках нельзя.
Как мы реализовали мультиконференции:
Использование отдельных WebRTC-сессий: для каждого подключения создаётся отдельный временный токен, что позволяет переключаться между встречами без потери соединения.
Динамическое управление аудио и видео: WebRTC позволяет сохранить активные соединения для всех встреч, а динамическое управление аудио-видео потоками снижает нагрузку на браузер.
В заключение
Наши доработки позволили получить комплексное решение, удобное для повседневной работы сотрудников и масштабируемое для крупных мероприятий. Надеемся, наш опыт будет вам полезен и пригодится при решении схожих задач.
О Squadus и Squadus PRO мы подробно рассказываем на страницах нашего сайта, посвященных этим продуктам. А если у вас появятся вопросы по реализации ВКС, будем рады ответить на них в комментариях.
Узнать больше о том, как мы разрабатывали Squadus вы можете из предыдущих статей нашего цикла:
Как мы создаем Squadus: улучшение UX в новом продукте
Как мы создаём Squadus: реальна ли выгода от использования open-source?
Как мы создаем Squadus: путешествие от монолита к микросервисам
Как мы создаем Squadus: проблемы фронтенда и пути их решения
Как мы создаём Squadus. Реализуем «прыжок к сообщению» в мобильной версии
Комментарии (4)
werter_l
16.11.2024 05:21Здравствуйте. Спасибо за статью.
Джитси - продукт открытый, будет ли коммиты от Вас отправлены в джитси или появятся от на гитхабе?
ilikeintegratedcircuit Автор
16.11.2024 05:21Привет
Мы сотрудничаем с коллегами из Jitsi в рамках обнаружения и устранения неисправностей. В настоящий момент наработки МойОфис не так актуальны для сообщества. Если у нас появятся полезные материалы в будущем, мы опубликуем их.
ugenef_dev
Спасибо за статью!
Вопрос:
Вы измеряли предельное количество участников в обычных видеокомнатах? Какой функционал начинает деградировать при большом числе участников, и как это отражается на клиенте (особенно на мобильном)? Как растёт потребление CPU\памяти с ростом комнаты?
ilikeintegratedcircuit Автор
Привет
В обычных конференциях мы выдерживаем порядка 250 пользователей в зависисмоти от настроек качества и характера нагрузки. При большом количестве участников в первую очередь перестает отображаться видео на плитках участников, если много пользователей включили камеру. Видеопоток и звук от говорящего при этом идет нормально
С мобильным клиентом не проводили замеры. А замеры потребления CPU/памяти в общем то у нас коррелируют со статьей https://medium.com/@ksotik/нагрузочное-тестирование-jitsi-open-source-аналога-zoom-47c2c16d4a6d