Real-Time Backend

Signaling сервер

WebRTC P2P напрямую устанавливает соединение между двумя браузерами через NAT - но кто-то должен их сначала познакомить. Signaling сервер делает это за 10-20 сообщений, после чего полностью выходит из игры.

  • **Livekit** (open-source WebRTC platform) использует Redis pub/sub для signaling между инстансами: каждый WebSocket server подписывается на каналы своих rooms и форвардит сообщения через Redis. Горизонтально масштабируется до тысяч инстансов
  • **Daily.co** генерирует временные TURN credentials со сроком 24ч через свой signaling API. Каждый join-запрос возвращает свежие credentials - злоупотребление credentials конкретного пользователя ограничено TTL
  • **Twilio Video** публикует статистику: их signaling сервера обрабатывают пик в 50 млн сообщений в день (SDP + ICE candidates) при минимальной вычислительной нагрузке - это чистый relay
  • **Cloudflare Calls** предоставляет managed signaling + TURN. Разработчику не нужно поднимать свой сервер - только клиентский SDK и один API endpoint

Signaling Role

Signaling server - это 'свидетель' при установке WebRTC соединения. Он не обрабатывает медиа, не декодирует видео, не хранит данные. Его единственная задача - передать SDP и ICE candidates между двумя peers до того, как они смогут общаться напрямую.

WebRTC намеренно не стандартизирует signaling протокол - это решение оставлено разработчику. Можно использовать WebSocket, Server-Sent Events, даже QR-код или email. На практике 99% реализаций используют WebSocket из-за двунаправленности и низкой latency.

**Масштаб:** Signaling server для 10000 одновременных WebRTC сессий обрабатывает примерно 10-50 сообщений на сессию (SDP + ICE candidates). Это ~100-500K сообщений за сессионный пик. После установки соединений нагрузка падает почти до нуля - только heartbeat. Signaling горизонтально масштабируется, в отличие от TURN сервера.

После успешного Offer/Answer обмена и ICE negotiation - какую роль продолжает играть signaling server?

Signaling Protocol

Несмотря на то что WebRTC не стандартизирует signaling, на практике сложился де-факто стандарт: JSON-сообщения с полем `type` через WebSocket. Минимальный набор типов: `offer`, `answer`, `ice-candidate`, `hangup`.

**Масштабирование signaling:** простой relay работает пока все peers подключены к одному server-инстансу. При горизонтальном масштабировании нужен pub/sub (Redis, NATS) для cross-instance relay. Livekit (open-source WebRTC platform) использует Redis pub/sub для signaling между инстансами.

Signaling сервер масштабируется горизонтально на 3 инстанса. Alice на инстансе 1, Bob на инстансе 2. Как relay сообщения от Alice до Bob?

Perfect Negotiation

В WebRTC race condition - это не edge case, это штатная ситуация. Alice создаёт offer, Bob тоже создаёт offer одновременно. Оба получают offer от другого пока у самих уже есть local offer. Это называется **glare** - столкновение offer'ов. Без обработки glare соединение зависает.

**Perfect Negotiation** - паттерн из WebRTC спецификации W3C для корректной обработки glare без сложной координации. Идея: один peer назначается 'polite' (уступает), другой - 'impolite' (настаивает). При glare polite-peer откатывает свой offer и принимает offer от impolite-peer.

**Implicit rollback:** `await pc.setRemoteDescription(sdp)` когда signalingState='have-local-offer' раньше требовал явного `setLocalDescription({type:'rollback'})`. В современных браузерах (Chrome 80+, Firefox 75+) setRemoteDescription делает implicit rollback автоматически - именно это делает Perfect Negotiation лаконичным.

В Perfect Negotiation паттерне что делает 'polite' peer при получении offer во время glare (когда сам создаёт offer)?

Signaling Impl

Production signaling сервер должен решать несколько задач за пределами базового relay: аутентификация WebSocket соединения, room management, обработка reconnect, rate limiting против DoS. Рассмотрим production-ready структуру.

**TURN credentials rotation:** статические TURN credentials в коде - уязвимость. Production подход: signaling сервер генерирует временные TURN credentials (TTL 24ч) через REST API coturn/Cloudflare TURN. Клиент запрашивает credentials при join, получает `{ username, credential, ttl }` и использует для RTCPeerConnection. Twilio, Daily.co генерируют credentials на своих бекендах именно так.

Signaling сервер - это TURN сервер; они делают одно и то же

Signaling и TURN - разные серверы с разными задачами: signaling обменивает SDP/ICE metadata (текст, низкий трафик), TURN relay-ит медиапоток (видео/аудио, высокий трафик)

Signaling сервер после установки соединения почти не нагружен - только редкие renegotiation events. TURN сервер при активной сессии передаёт мегабиты видео непрерывно. Они масштабируются по-разному: signaling - stateless WebSocket relay, TURN требует широкой сетевой полосы. Смешивать их в одном сервисе - архитектурная ошибка.

Почему TURN server credentials не следует хардкодить в клиентском коде?

Итоги

  • Signaling server - relay для SDP/ICE metadata; после P2P handshake его нагрузка падает до нуля; масштабируется через Redis pub/sub
  • Perfect Negotiation решает glare (collision offers) через polite/impolite роли; polite peer делает rollback своего offer при получении чужого
  • TURN credentials должны быть временными (TTL 24ч) и генерироваться signaling сервером per-session; хардкод credentials открывает relay для злоупотребления

Связанные темы

Signaling сервер - точка интеграции WebRTC с остальным backend:

  • WebRTC основы — Предыдущий урок: архитектура P2P, ICE, SDP - база для понимания что именно relay-ит signaling сервер
  • WebSocket сервер — Signaling использует WebSocket как транспорт; те же паттерны room management и message routing применимы к обоим
  • Аутентификация WebSocket — JWT в query parameter при WS upgrade - стандартный паттерн auth для signaling; те же механизмы что и в WS auth уроке

Вопросы для размышления

  • Signaling протокол не стандартизирован в WebRTC спецификации. Какие преимущества и недостатки даёт эта свобода разработчику?
  • Perfect Negotiation требует определить кто 'polite' а кто 'impolite'. Как это делать в группе из 3+ участников, где каждый может инициировать renegotiation?
  • При reconnect (разрыв соединения) нужно ли начинать Offer/Answer заново или можно продолжить с существующим RTCPeerConnection через ICE restart?

Связанные уроки

  • net-36-websocket
Signaling сервер

0

1

Войти