WebRTC
Что такое WebRTC?
WebRTC
(Web Real-Time Communication - коммуникация в режиме реального времени) - это API (Application Programming Interface - программный интерфейс приложения) и протокол. Протокол WebRTC
- это набор правил, позволяющий двум агентам WebRTC
(браузерам) вести двунаправленную (bi-directional) безопасную коммуникацию в реальном времени. WebRTC API
позволяет разработчикам использовать протокол WebRTC
. WebRTC API
в настоящее время определен только для JavaScript
.
Возможно, вам уже известна другая пара с похожим взаимодействием HTTP и Fetch API. В нашем случае протокол WebRTC
- это HTTP
, а WebRTC API
- это Fetch API
.
Протокол WebRTC
поддерживается рабочей группой rtcweb IETF. WebRTC API
задокументирован в W3C как webrtc.
Зачем изучать WebRTC?
Если попытаться кратко описать особенности WebRTC
, получится вот такой список. Притом он не является исчерпывающим, это просто примеры интересных характеристик, с которыми вы встретитесь, изучая WebRTC
. Не волнуйтесь, если не знакомы с какими-то терминами, все они будут раскрыты далее:
- Открытый стандарт
- Разные реализации
- Доступность в браузерах
- Обязательное шифрование
- Отображение NAT (NAT Traversal)
- Перепрофилирование существующих технологий
- Контроль перегрузки (congestion control)
- Низкая задержка (на уровне долей секунды, sub-second latency)
Протокол WebRTC - это собрание других технологий
В процессе установки соединения с помощью WebRTC
можно выделить 4 этапа:
- Сигнализация (signalling)
- Подключение (установка соединения) (connection)
- Безопасность (securing)
- Коммуникация (взаимодействие) (communication)
Переходы между этапами происходят последовательно. Обязательным условием для начала следующего этапа является успешное завершение предыдущего.
Интересный факт о WebRTC
- каждый этап состоит из большого количества других протоколов. Для создания WebRTC
было объединено множество существующих технологий. В этом смысле WebRTC
- это комбинация и конфигурация хорошо известных технологий, появившихся в начале 2000-х годов.
Каждому из перечисленных 4 этапов посвящен отдельный раздел, но для начала давайте рассмотрим их на самом высоком уровне. Поскольку этапы зависят друг от друга, в дальнейшем это облегчит объяснение и понимание назначения каждого из них.
Сигнализация: как пиры (peers) находят друг друга
При запуске WebRTC
агент не знает, с кем и по поводу чего будет происходит коммуникация. И именно сигнализация дает нам прозрачность. Это первый этап и его назначение – подготовка вызова (звонка) (call) для того, чтобы два агента WebRTC
могли начать коммуникацию.
Сигнализация осуществляется с помощью существующего протокола SDP
(Session Description Protocol - протокол описания сессии). Напомним, что SDP
– это текстовый протокол. Каждое сообщение SDP
состоит из нескольких пар ключ/значение и содержит список "медиа разделов" (media sections). SDP
, которыми обмениваются агенты WebRTC
, содержит следующую информацию:
-IP и порты, по которым можно получить доступ к агенту (candidates - кандидаты);
- какое количество аудио и видео треков хочет отправить агент;
- какие аудио и видео кодеки поддерживаются каждым агентом;
- значения, используемые в процессе подключения (
uFrag/uPwd
); - значения, используемые для обеспечения безопасности (certificate fingerprint - отпечаток сертификата).
Обратите внимание, что сигнализация, как правило, происходит вне WebRTC
; WebRTC
, обычно, не используется для передачи сигнальных сообщений (signalling messages). Для передачи SDP
между подключенными пирами могут использоваться такие технологии, как конечные точки REST, веб-сокеты или прокси аутентификации (authentication proxies).
Подключение и отображение NAT с помощью STUN/TURN
В процессе сигнализации агенты WebRTC
получают достаточно информации для того, чтобы попытаться выполнить подключение. Для этого используется другая технология под названием ICE
.
ICE
(Interactive Connectivity Establishment - установка интерактивного соединения) - это еще один протокол, предшествующий появлению WebRTC
. ICE
позволяет устанавливать соединение между двумя агентами. Агенты могут находиться в одной (локальной) сети или в разных концах света. ICE
- это решение для установки прямого соединения без центрального сервера.
Настоящее волшебство - это "отображение NAT" и серверы STUN/TURN
. И это все, что вам нужно для коммуникации с агентом ICE
, находящимся в другой подсети (subnet).
После успешного подключения ICE
WebRTC
приступает к установке зашифрованного транспортного канала. Он используется для передачи аудио, видео и других данных.
Обеспечение безопасности канала передачи данных с помощью DTLS и SRTP
После того, как мы установили двунаправленный канал коммуникации (с помощью ICE
), нам необходимо сделать этот канал безопасным. Это делается с помощью двух протоколов, также разработанных задолго до появления WebRTC
. Первый протокол - это DTLS
(Datagram Transport Layer Security - протокол датаграмм безопасности транспортного уровня), который является просто TLS
поверх UDP
. TLS
- это криптографический протокол, который используется для безопасной коммуникации через HTTPS
. Второй протокол - это SRTP
(Secure Real-time Transport Protocol - используется для безопасной передачи данных в реальном времени).
Сначала WebRTC
выполняет рукопожатие (handshake) DTLS
с помощью соединения ICE
. В отличие от HTTPS
, WebRTC
не использует центральный орган (central authority) для проверки сертификатов. Вместо этого WebRTC
проверяет, что сертификат, переданный через DTLS
, совпадает с отпечатком (fingerprint, мы подробно поговорим об этом в разделе, посвященном безопасности), переданным в процессе сигнализации. В дальнейшем DTLS-подключение
используется для передачи сообщений по DataChannel
(каналу передачи данных).
Для передачи аудио/видео используется другой протокол под названием RTP
(Real-time Transport Protocol - протокол передачи данных в реальном времени). Пакеты, передаваемые по RTP
, защищаются с помощью SRTP
. Сессия SRTP
начинается с извлечения ключей из установленной сессии DTLS
.
Поздравляем! Если предыдущие этапы завершились успешно, у нас имеется двунаправленная и безопасная коммуникация. Если соединение между агентами WebRTC
является стабильным, можно приступать к обмену данными. К сожалению, в реальном мире мы постоянно сталкиваемся с потерей пакетов и ограниченной пропускной способностью, о чем мы поговорим в следующем разделе.
Коммуникация между пирами через RTP и SCTP
Итак, мы установили безопасное двунаправленное соединение между двумя агентами WebRTC
и наконец-то приступаем к коммуникации! Для этого используется два протокола: RTP
и SCTP (Stream Control Transmission Protocol — протокол передачи с управлением потоком). RTP
используется для передачи медиа, зашифрованного с помощью SRTP
, а SCTP
- нужен для отправки и приема сообщений по DataChannel
, зашифрованных с помощью DTLS
.
RTP
является довольно минималистичным, но он предоставляет все необходимое для потоковой передачи данных в реальном времени. Гибкость RTP
позволяет разработчикам решать проблемы, связанные с задержкой, потерей данных и перегрузкой, самыми разнообразными способами.
Последним протоколом в стеке является SCTP
. Он предоставляет множество настроек, связанных с доставкой сообщений. Мы, например, можем пожертвовать надежностью и правильным порядком доставки пакетов данных в пользу низкой задержки доставки. Именно она является критически важной для коммуникации в реальном времени.
WebRTC - коллекция протоколов
На первый взгляд WebRTC
может показ аться перепроектированным (over-engineered). Но мы можем ему это простить, так как с его помощью мы можем решать большое количество проблем. Гениальность WebRTC
заключается в его скромности: он не пытается решать все задачи самостоятельно. Вместо этого, он объединяет множество существующих специализированных технологий в единое целое.
Это позволяет исследовать и изучать каждую часть по-отдельности. Очень подходящее сравнение WebRTC
– это оркестратор (orchestrator) большого количества других протоколов.

Как работает WebRTC (API)?
В этом разделе мы поговорим о том, как протокол WebRTC
реализован в JavaScript API
. Это не подробный обзор, а всего лишь попытка нарисовать общую картину того, что происходит в процессе коммуникации в реальном времени.
new RTCPeerConnection
RTCPeerConnection
- "WebRTC-сессия" верхнего уровня. Она объединяет все упомянутые выше протоколы. Выполняется подготов ка всех необходимых подсистем, но пока еще ничего не происходит.
addTrack
addTrack
создает новый поток данных (stream) RTP
. Для этого потока генерируется случайный источник синхронизации (Synchronization Source, SSRC
). Поток находится внутри описания сессии (Session Description, SDP
) (в медиаразделе), генерируемого createOffer
. Каждый вызов addTrack
создает новый SSRC
и медиараздел.
После установки SRTP-сессии
и шифрования, эти медиапакеты начинают передаваться через ICE
.
createDataChannel
createDataChannel
создает новый SCTP-поток
при его отсутствии. По умолчанию SCTP
отключен, он включается только при запросе любой стороной канала передачи данных.
После установки DTLS-сессии
и шифрования, эти пакеты с данными начинают передаваться через ICE
.
createOffer
createOffer
генерирует описание локального состояния (local state) сессии, передаваемого удаленному (в значении "находящемуся далеко", remote) пиру.
Вызов createOffer
ничего не меняет для локального пира.
setLocalDescription
setLocalDescription
фиксирует (commits) запроше нные (произведенные) изменения. addTrack
, createDataChannel
и аналогичные вызовы являются временными до вызова setLocalDescription
. setLocalDescription
вызывается со значением, сгенерированным createOffer
.
setRemoteDescription
setRemoteDescription
– способ информирования локального агента о состоянии удаленных кандидатов. Это сигнализация, выполняемая JavaScript API
.
После вызова setRemoteDescription
обеими сторонами, агенты WebRTC
имеют достаточно информации для начала коммуникации P2P
(Peer-To-Peer - равный к равному).
addIceCandidate
addIceCandidate
позволяет WebRTC-агенту
добавлять дополнительных кандидатов ICE
в любое время. Данный интерфейс отправляет кандидата ICE
прямо в подсистему ICE
и не оказывает никакого другого влияния на общее соединение.
ontrack
ontrack
- это функция обратного вызова (callback), которая вызывается при получении RTP-пакета
от удаленного пира. Входящие пакеты помещаются в описание сессии, которое передается в setRemoteDescription
.
oniceconnectionstatechange
oniceconnectionstatechange
- это колбэк, который вызывается при изменении состояния агента ICE
. Так мы получаем уведомления об установке и завершении соединения.
onconnectionstatechange
onconnectionstatechange
- это комбинация состояния ICE
и DTLS
. Мы можем использовать этот коллбэк для получения уведомления об успешной установке ICE
и DTLS
.
Сигнализация
В момент своего создания агент WebRTC
ничего не знает о другом пире. Он не имеет ни малейшего представления о том, с кем будет установлено соединение и чем они будут обмениваться. Сигнализация - это подготовка к совершению звонка. После обмена необходимой информацией агенты могут общаться друг с другом напрямую.
Сообщения, передаваемые в процессе сигнализации - это просто текст. Агентам неважно, как они передаются (какой транспорт для этого используется). Как правило, они передаются через веб-сокеты, но это необязательно.