WebRTC

WebRTC (Web Real-Time Communication) — набор стандартов и API для P2P передачи медиа (аудио/видео) и произвольных данных в браузере без плагинов. Основа Google Meet, Discord, Zoom Web Client, Facebook Messenger, WhatsApp Web, всех «звонков в браузере». Разрабатывается W3C и IETF, стабильно с 2017.

Три главных API

  1. getUserMedia — доступ к микрофону и камере. Возвращает MediaStream.
  2. RTCPeerConnection — управление соединением с пиром, ICE, DTLS, SRTP, кодирование медиа.
  3. RTCDataChannel — произвольные данные (SCTP over DTLS over UDP).

Компоненты стека

┌────────────────────────────────────┐
│  Медиа (VP8/VP9/AV1/H.264/H.265,   │
│         Opus, PCMU, PCMA)          │
├────────────────────────────────────┤
│  SRTP / SRTCP                       │  ← шифрованное RTP
├────────────────────────────────────┤
│  DTLS-SRTP                          │  ← handshake для медиа-ключей
├────────────────────────────────────┤
│  SCTP (для DataChannel)             │
├────────────────────────────────────┤
│  DTLS                                │
├────────────────────────────────────┤
│  ICE / STUN / TURN                  │  ← ICE, STUN, TURN
├────────────────────────────────────┤
│  UDP (или TCP как fallback)         │
└────────────────────────────────────┘

Signaling

WebRTC не задаёт способ обмена начальными параметрами (offer/answer + ICE-кандидаты). Signaling делаешь сам — обычно через WebSocket или SSE к своему серверу.

Классический offer/answer:

  1. Alice создаёт RTCPeerConnection, добавляет свой MediaStream.
  2. Alice: createOffer() → SDP. Через сигналинг шлёт Bob.
  3. Bob: setRemoteDescription(offer), добавляет свой поток, createAnswer() → SDP. Шлёт Alice.
  4. Alice: setRemoteDescription(answer).
  5. Оба собирают ICE-кандидаты и обмениваются ими через сигналинг (trickle).
  6. ICE находит рабочий путь → DTLS-handshake → медиа течёт.

Простой пример

const pc = new RTCPeerConnection({
    iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
});

// Медиа
const stream = await navigator.mediaDevices.getUserMedia({video:true, audio:true});
stream.getTracks().forEach(track => pc.addTrack(track, stream));

// Приём удалённого
pc.ontrack = (ev) => {
    document.getElementById('remote').srcObject = ev.streams[0];
};

// ICE-кандидаты
pc.onicecandidate = (ev) => {
    if (ev.candidate) signaling.send({candidate: ev.candidate});
};

// Offer/answer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({sdp: offer});

Data Channels

const dc = pc.createDataChannel('game', {ordered: false, maxRetransmits: 0});
dc.onopen = () => dc.send('hi');
dc.onmessage = (ev) => console.log(ev.data);
dc.binaryType = 'arraybuffer';

Параметры:

Топологии

ТопологияИспользованиеCost
Peer-to-Peer1:1 звонокНагрузка на клиента, минимум сервера
MeshМаленькие групповые (3-5 человек). Каждый шлёт всемN² upload у каждого клиента
SFU (Selective Forwarding Unit)10-50 участников. Сервер получает потоки и раздаётУмеренная серверная нагрузка
MCU (Multipoint Control Unit)Сотни участников, транскодингДорого — CPU-heavy

Media SFU

Популярные SFU:

Кодеки

ТипКодеки
АудиоOpus (default), G.711 (PCMU/PCMA), G.722, iSAC (deprecated)
ВидеоVP8, VP9, H.264, AV1 (с 2021), H.265 (в Safari 12.1+)

Opus — де-факто стандарт для VoIP. 8-510 kbps, адаптивный, латентность 5-60 мс.

Простыми словами про SRTP

Медиа шифруется SRTP (Secure RTP). Ключи для SRTP извлекаются из DTLS-handshake — механизм называется DTLS-SRTP. Отпечаток сертификата DTLS передаётся в SDP через a=fingerprint:sha-256 ... — стороны проверяют что подключились именно к тем.

Приватность

Не-браузерные реализации

WebRTC-NV (Next Version)

Активная разработка новых API поверх WebRTC-транспортов:

См. также