Slyber SFU Server — WebRTC медиароутер для звонков, вебинаров и ИИ ботов

Привет Хабр! 👋

В этом обзоре я простым языком расскажу, что такое Slyber SFU Server зачем он нужен, как устроен внутри и какие задачи он решает.

Slyber SFU Server — это сервер селективной маршрутизации аудио, видео и данных в реальном времени, написанный на Go. Он поставляется в виде одного бинарного файла без внешних зависимостей и закрывает задачи групповых видеоконференций, звонков 1 на 1 и голосовых диалогов с ИИ агентами. Также есть возможность установки через Docker одной командой.

Зачем вообще нужен SFU

Когда два человека созваниваются в браузере напрямую, их устройства обмениваются видео и аудио без посредников. Но если в комнату заходят 10 человек, то прямое соединение ломается браузер каждого участника вынужден сжимать и отправлять в сеть 9 отдельных копий своего видео/аудио по одной для каждого собеседника. Телефон быстро греется и батарея быстрее разряжается.

SFU (Selective Forwarding Unit) работает как почтовый сортировщик

  1. Вы отправляете на сервер один видеопоток.

  2. Сервер копирует готовые пакеты и рассылает их остальным участникам комнаты.

  3. За счёт этого одна серверная нода способна одновременно обслуживать до 5000 активных комнат.

Что умеет Slyber SFU Server

Я проектировал сервер так, чтобы его можно было развернуть на чистом Linux сервере за одну минуту без ручной правки конфигов. Также быстро можно установить данное решение и в Docker контейнер без каких либо доп настроек. Вот из чего состоит система:

1. Один порт :4443 для UDP и TCP

В Slyber SFU Server весь медиатрафик всех комнат идёт через один порт 4443. На входе стоят мультиплексоры ICEUDPMux и ICETCPMux (стандарт RFC 4571):

  • Если пользователь подключается из дома или с мобильного интернета — трафик летит по UDP на порт 4443.

  • Если пользователь сидит в корпоративной сети, где админы заблокировали UDP — браузер автоматически подключается по TCP на тот же самый порт 4443.

  • Отдельный порт 8090/TCP отвечает за WebSocket сигналинг (/ws), шлюзы вещания и метрики.

2. Адаптация под слабый интернет

На одном звонке могут сидеть люди с гигабитной оптикой и люди в лифте с плохим 3G. Чтобы видео не зависало, сервер поддерживает многопоточный Simulcast (слои q, h, f — например, 270p, 540p и 1080p) и масштабируемый кодек VP9 SVC.

Встроенный контроллер пропускной способности SubscriberBWE постоянно следит за отчётами от каждого зрителя (TWCC, REMB, RTCP Receiver Report). Как только у конкретного зрителя падает скорость или растут потери пакетов, сервер плавно переводит лично его на лёгкий слой, не ухудшая картинку остальным.

Чтобы при потерях пакетов отправителя не заваливало запросами ключевых кадров, для каждого слоя работают:

  • собственный кольцевой буфер NACK на 512 пакетов

  • независимый фильтр PLICoalescer с интервалом 500 мс.

3. Экономия трафика в конференциях

В групповом созвоне на 30 человек нет смысла передавать видео всех 28 молчунов. Сервер считывает уровень громкости из открытого заголовка аудиопакета RFC 6464 (ssrc-audio-level), не расшифровывая сам голос. Механизм EnforceLastNVideo автоматически ставит на паузу камеры тех, кто молчит, и мгновенно включает видео обратно с ключевого кадра, как только человек начинает говорить.

4. Свап собеседника в звонках 1 на 1

В обычном WebRTC при переключении собеседника приходится заново обмениваться SDP Offer/Answer, из за чего зритель видит чёрный экран 1–2 секунды.

Для профиля roulette_1v1 в Slyber SFU реализован метод FastSwapRouletteTrack. Потоки следующих кандидатов заранее прогреты на входе, а переключение происходит сменой внутреннего указателя. Модуль SeqTimestampRewriter на лету выравнивает номера пакетов (SequenceNumber) и таймстампы нового собеседника так, чтобы браузер зрителя воспринимал поток как непрерывный без разрывов и ренегоциации SDP.

5. Готовый шлюз /ai/ws для голосовых ИИ агентов

Чтобы добавить в звонок голосового бота на базе Gemini Live или OpenAI Realtime API, не нужно поднимать тяжёлый WebRTC стек на Python или Node.js. Достаточно подключить ИИ бэкенд к встроенному WebSocket шлюзу /ai/ws:

  • Мультиплексирование (mode=mux): через одно WebSocket соединение можно запустить в комнату до 6 независимых ботов с разными голосами у каждого будет свой SSRC и отдельный аудиотрек.

  • Пейсер на 20 мс: нейросети отдают звук неравномерными пачками; сервер складывает их в буфер и выпускает в комнату ровно каждые 20 мс с правильным шагом таймстампа.

  • Перебивание: как только человек начинает говорить (3 голосовых фрейма подряд по заголовку RFC 6464), сервер мгновенно очищает очередь несказанных слов бота и отправляет вашему бэкенду событие ai_vad_barge_in.

6. Вещание из OBS (WHIP/WHEP), MoQ и каскадирование серверов

  • WHIP и WHEP: можно запустить стрим напрямую из OBS Studio через POST /whip/{room}/{track} и раздавать его зрителям через POST /whep/{room}/{track} за один HTTP запрос с защитой владельца потока по ETag.

  • MoQ Relay: упаковка медиапотоков в объекты стандарта moqt-draft-22 (/moq/{room}/{track}).

  • Каскадирование (/cascade/): объединение нескольких серверов Slyber SFU в разных дата центрах по UDP с криптографической подписью каждого пакета HMAC-SHA256-128 и встроенной защитой от SSRF атак на локальные подсети.

7. Безопасность и 3 режима авторизации

  • Авторизация на выбор: встроенная проверка подписанных HS256 JWT токенов (с гибкими правами can_publish, can_subscribe, max_spatial_layer), пул соединений к Redis (мгновенный отзыв доступа при удалении ключа slyber:session:) или статические HMAC-SHA1 токены.

  • Сквозное шифрование SFrame E2EE: при включении REQUIRE_E2EE=true сервер проверяет криптографические заголовки RFC 9605 SFrame и 16 байтный GCM тег, поддерживает ротацию до 16 ключей MLS на каждый SSRC и защищает от реплей атак окном на 512 пакетов. При этом сервер не может расшифровать звук и видео, а слои маршрутизирует по открытому заголовку RFC 9626 Frame Marking.

  • Память и лимиты скорости: входящие пакеты обрабатываются через пул памяти sync.Pool с атомарным подсчётом ссылок без нагрузки на сборщик мусора Go, а шейпер TrafficPolice ограничивает битрейт на каждый трек и сессию.

Технические характеристики в одной таблице

Подсистема

Реализация в Slyber SFU Server

Стек и сборка

Go + pion/webrtc/v4; один статический бинарный файл для Linux и macOS (amd64, arm64)

Сетевой транспорт

Режим ICE-Lite; единый порт 4443 для UDP (ICEUDPMux) и TCP (RFC 4571 ICETCPMux); HTTP/WS шлюз на 8090; автотюнинг буферов ОС до 8 МБ

Кодеки

Видео: VP9 (включая SVC), AV1, H264, VP8; Аудио: Opus 48 кГц стерео с Inband FEC

Профили комнат

5 готовых режимов: conference, roulette_1v1, broadcast, gaming, ai_voice (до 5000 активных комнат на узел)

Качество и QoS

Simulcast (3 слоя), VP9 SVC, SubscriberBWE (TWCC/REMB/RR), послойные буферы NACK (512 пакетов), послойный PLICoalescer (500 мс), Last-N по RFC 6464

Шлюзы и кластер

WHIP/WHEP, полнодуплексный /ai/ws (mode=mux, пейсер 20 мс, VAD Barge-In), MoQ (moqt-draft-22), UDP-каскад /cascade/ с HMAC-SHA256-128

Безопасность

Режимы jwt, redis, secret; выделенный ключ NODE_SECRET; RFC 9605 SFrame E2EE + MLS; TrafficPolice rate limiter

Мониторинг

JSON телеметрия /inspector/stats, экспортер Prometheus /metrics и встроенная CLI-диагностика slyber-sfu doctor

Быстрый старт

Установить сервер на чистый Linux хост можно одной командой — скрипт сам скачает бинарник, проверит контрольную сумму SHA256SUMS, настроит сетевые буферы ядра, сгенерирует ключи в /opt/slyber_sfu/.env, откроет порт 4443 и запустит службу systemd:

curl -fsSL https://raw.githubusercontent.com/slyber-app/slyber-sfu-server/main/install.sh | sudo bash

Или запустить в Docker из официального реестра GitHub Container Registry:

docker pull ghcr.io/slyber-app/slyber-sfu-server:latestdocker rm -f slyber-sfu-server 2>/dev/null || truePUBLIC_IP=$(curl -fsSL4 --max-time 2 api.ipify.org 2>/dev/null || echo 127.0.0.1)JWT_SECRET=$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' n')NODE_SECRET=$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' n')docker run -d  --name slyber-sfu-server  --restart unless-stopped  --network host  -e SFU_ENV="production"  -e PUBLIC_IP="${PUBLIC_IP}"  -e SFU_UDP_PORT="4443"  -e SFU_TCP_PORT="4443"  -e SFU_HTTP_PORT="8090"  -e AUTH_MODE="jwt"  -e JWT_SECRET="${JWT_SECRET}"  -e NODE_SECRET="${NODE_SECRET}"  ghcr.io/slyber-app/slyber-sfu-server:latest &&  sleep 1 &&  docker exec slyber-sfu-server slyber_sfu doctor &&  echo "Public IP : ${PUBLIC_IP}" &&  echo "JWT Secret : ${JWT_SECRET}" &&  echo "Node Secret: ${NODE_SECRET}" &&  echo "Test Token : $(curl -fsS -H "X-Slyber-Node-Secret: ${NODE_SECRET}" "http://127.0.0.1:8090/auth/token?room=test-room&user=user-1")"

Проверить здоровье запущенного узла можно встроенной командой самодиагностики:

$ slyber-sfu doctor================================================================ SLYBER SFU DOCTOR | Version: v1.0.0 | Node: slyber-sfu-01================================================================ [OK] Environment : production [OK] Public IP & Realm : 89.111.175.67 (slyber.com) [OK] Pion ICE Mux : UDP :4443 | TCP :4443 (ICE-TCP=true) | HTTP :8090 [OK] Auth & Security : jwt (E2EE=true, External TURN=1) [OK] All Slyber SFU self-diagnostics passed.================================================================

Ссылки на проект и документацию

  • GitHub

  • Документация

  • Технический кейс

Источник: habr.com

0 0 голоса
Рейтинг новости
1
0
Подписаться
Уведомить о
0 комментариев