WebRTC — это новый фронт в долгой войне за открытый и свободный Интернет.
Брендан Эйх, изобретатель JavaScript
Общение в реальном времени без плагинов
Представьте себе мир, в котором ваш телефон, телевизор и компьютер могут взаимодействовать на общей платформе. Представьте, что добавить видеочат и обмен данными по сети P2P в ваше веб-приложение стало легко. В этом и заключается концепция WebRTC.
Хотите попробовать? WebRTC доступен на компьютерах и мобильных устройствах в Google Chrome, Safari, Firefox и Opera. Хорошей отправной точкой станет простое приложение для видеочата на appr.tc :
- Откройте appr.tc в вашем браузере.
- Нажмите «Присоединиться» , чтобы присоединиться к чату и разрешить приложению использовать вашу веб-камеру.
- Откройте URL-адрес, отображаемый в конце страницы, в новой вкладке или, что еще лучше, на другом компьютере.
Быстрый старт
Нет времени читать эту статью или вам нужен только код?
- Чтобы получить общее представление о WebRTC, посмотрите следующее видео Google I/O или просмотрите эти слайды :
- Если вы еще не использовали API
getUserMedia
, см. раздел Захват аудио и видео в HTML5 и simpl.info getUserMedia . - Чтобы узнать больше об API
RTCPeerConnection
, ознакомьтесь со следующим примером и «simpl.info RTCPeerConnection» . - Чтобы узнать, как WebRTC использует серверы для сигнализации, а также обхода брандмауэра и NAT, просмотрите код и журналы консоли из appr.tc.
- Не терпится попробовать WebRTC прямо сейчас? Попробуйте более 20 демонстраций , демонстрирующих возможности JavaScript API WebRTC.
- Возникли проблемы с вашим устройством и WebRTC? Посетите страницу устранения неполадок WebRTC .
В качестве альтернативы вы можете сразу перейти к практическому руководству по WebRTC — пошаговому руководству, в котором объясняется, как создать полноценное приложение для видеочата, включая простой сигнальный сервер.
Очень краткая история WebRTC
Одна из последних серьёзных задач для интернета — обеспечение возможности человеческого общения посредством голоса и видео: общение в реальном времени, или сокращённо RTC. RTC должно быть таким же естественным в веб-приложении, как ввод текста в текстовое поле. Без него ваши возможности для инноваций и разработки новых способов взаимодействия ограничены.
Исторически RTC был корпоративным и сложным, требуя лицензирования или разработки дорогостоящих аудио- и видеотехнологий собственными силами. Интеграция технологий RTC с существующим контентом, данными и сервисами была сложной и трудоёмкой, особенно в интернете.
Видеочат Gmail стал популярным в 2008 году, а в 2011 году Google представил Hangouts, использующий Talk (как и Gmail). Google приобрела компанию GIPS, которая разработала множество компонентов, необходимых для RTC, таких как кодеки и методы эхоподавления. Google открыла исходный код технологий, разработанных GIPS, и сотрудничала с соответствующими организациями по стандартизации, такими как IETF и W3C, для обеспечения отраслевого консенсуса. В мае 2011 года Ericsson разработала первую реализацию WebRTC .
WebRTC реализовал открытые стандарты для передачи видео, аудио и данных в режиме реального времени без плагинов. Потребность была реальной:
- Многие веб-сервисы использовали RTC, но требовали загрузки, собственных приложений или плагинов. К ним относятся Skype, Facebook и Hangouts.
- Загрузка, установка и обновление плагинов — сложный, подверженный ошибкам и раздражающий процесс.
- Плагины сложно развёртывать, отлаживать, устранять неполадки, тестировать и поддерживать, а также может потребоваться лицензирование и интеграция со сложными и дорогостоящими технологиями. Зачастую бывает сложно убедить людей установить плагины!
Руководящие принципы проекта WebRTC заключаются в том, что его API должны быть открытыми, бесплатными, стандартизированными, встроенными в веб-браузеры и более эффективными, чем существующие технологии.
Где мы сейчас?
WebRTC используется в различных приложениях, таких как Google Meet. WebRTC также интегрирован с приложениями WebKitGTK+ и Qt.
WebRTC реализует следующие три API: - MediaStream
(также известный как getUserMedia
) - RTCPeerConnection
- RTCDataChannel
API определены в следующих двух спецификациях:
Все три API поддерживаются на мобильных устройствах и компьютерах браузерами Chrome, Safari, Firefox, Edge и Opera.
getUserMedia
: Демонстрации и код см. в примерах WebRTC или попробуйте потрясающие примеры Криса Уилсона, которые используют getUserMedia
в качестве входных данных для веб-аудио.
RTCPeerConnection
: Простую демонстрацию и полнофункциональное приложение для видеочата можно найти в примерах WebRTC Peer connection и appr.tc соответственно. Это приложение использует adapter.js — JavaScript-оболочку, поддерживаемую Google при поддержке сообщества WebRTC , — чтобы абстрагироваться от различий браузеров и изменений спецификаций.
RTCDataChannel
: чтобы увидеть это в действии, ознакомьтесь с примерами WebRTC и просмотрите одну из демонстраций каналов данных.
В лабораторной работе WebRTC показано, как использовать все три API для создания простого приложения для видеочата и обмена файлами.
Ваш первый WebRTC
Приложения WebRTC должны выполнять несколько функций:
- Получайте потоковое аудио, видео и другие данные.
- Получайте сетевую информацию, такую как IP-адреса и порты, и обменивайтесь ею с другими клиентами WebRTC (известными как пиры ), чтобы обеспечить соединение даже через NAT и брандмауэры.
- Координировать сигнальную коммуникацию для сообщения об ошибках и инициирования или закрытия сеансов.
- Обмен информацией о возможностях мультимедиа и клиента, таких как разрешение и кодеки.
- Передавайте потоковое аудио, видео или данные.
Для сбора и передачи потоковых данных WebRTC реализует следующие API:
-
MediaStream
получает доступ к потокам данных, например, с камеры и микрофона пользователя. -
RTCPeerConnection
обеспечивает аудио- и видеосвязь с возможностями шифрования и управления полосой пропускания. -
RTCDataChannel
обеспечивает одноранговую передачу общих данных.
(Подробное обсуждение сетевых и сигнальных аспектов WebRTC приведено ниже.)
API MediaStream
(также известный как API getUserMedia
)
API MediaStream
представляет собой синхронизированные потоки медиаконтента. Например, поток, полученный с камеры и микрофона, содержит синхронизированные видео- и аудиодорожки. (Не путайте MediaStreamTrack
с элементом <track>
, который представляет собой совершенно разные вещи.)
Вероятно, самый простой способ понять API MediaStream
— это взглянуть на него вживую:
- В браузере перейдите к примерам WebRTC
getUserMedia
. - Откройте консоль.
- Проверьте переменную
stream
, которая находится в глобальной области видимости.
Каждый MediaStream
имеет вход, который может быть MediaStream
, сгенерированным методом getUserMedia()
, и выход, который может быть передан элементу видео или RTCPeerConnection
.
Метод getUserMedia()
принимает параметр объекта MediaStreamConstraints
и возвращает Promise
, который разрешается в объект MediaStream
.
Каждый MediaStream
имеет label
, например, 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Методы getAudioTracks()
и getVideoTracks()
возвращают массив MediaStreamTrack
.
В примере getUserMedia
stream.getAudioTracks()
возвращает пустой массив (поскольку звука нет), а при условии, что подключена работающая веб-камера, stream.getVideoTracks()
возвращает массив из одного MediaStreamTrack
, представляющего поток с веб-камеры. Каждый MediaStreamTrack
имеет тип ( 'video'
или 'audio'
), label
(например 'FaceTime HD Camera (Built-in)'
) и представляет один или несколько каналов аудио или видео. В данном случае есть только одна видеодорожка без звука, но легко представить себе варианты использования, где их больше, например, приложение для чата, принимающее потоки с фронтальной камеры, тыловой камеры, микрофона, а также приложение, демонстрирующее свой экран.
MediaStream
можно прикрепить к элементу видео, установив атрибут srcObject
. Ранее для этого нужно было задать в атрибуте src
URL-адрес объекта, созданный с помощью URL.createObjectURL()
, но этот метод устарел .
getUserMedia
также можно использовать как входной узел для API веб-аудио :
// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
console.log('Sorry! Web Audio not supported.');
}
// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;
// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;
navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
// Create an AudioNode from the stream.
const mediaStreamSource =
audioContext.createMediaStreamSource(stream);
mediaStreamSource.connect(filterNode);
filterNode.connect(gainNode);
// Connect the gain node to the destination. For example, play the sound.
gainNode.connect(audioContext.destination);
});
Приложения и расширения на базе Chromium также могут включать getUserMedia
. Добавление разрешений audioCapture
и/или videoCapture
в манифест позволяет запрашивать и предоставлять разрешения только один раз при установке. После этого у пользователя не будет запрашиваться разрешение на доступ к камере или микрофону.
Разрешение для getUserMedia()
необходимо предоставить только один раз. Впервые кнопка «Разрешить» отображается в информационной панели браузера. HTTP-доступ для getUserMedia()
был объявлен устаревшим в Chrome в конце 2015 года, поскольку он был классифицирован как « мощная функция» .
Целью является возможность использования MediaStream
для любого источника потоковых данных, а не только для камеры или микрофона. Это позволит транслировать потоковые данные из сохранённых данных или произвольных источников, таких как датчики или другие входные данные.
getUserMedia()
по-настоящему оживает в сочетании с другими JavaScript API и библиотеками:
- Webcam Toy — это приложение-фотобудка, которое использует WebGL для добавления странных и удивительных эффектов к фотографиям, которыми можно делиться или сохранять локально.
- FaceKat — игра с отслеживанием лиц, созданная с помощью headtrackr.js .
- ASCII Camera использует API Canvas для генерации изображений ASCII.

Ограничения
Ограничения можно использовать для задания значений разрешения видео для getUserMedia()
. Это также обеспечивает поддержку других ограничений , таких как соотношение сторон, режим обзора (фронтальная или задняя камера), частота кадров, высота и ширина, а также метод applyConstraints()
.
Для примера см. примеры WebRTC getUserMedia
: выбор разрешения .
Установка недопустимого значения ограничения приводит к возникновению исключения DOMException
или OverconstrainedError
, например, если запрошенное разрешение недоступно. Чтобы увидеть это в действии, см. примеры WebRTC getUserMedia
: выбор разрешения для демонстрации.
Снимок экрана и вкладки
Приложения Chrome также позволяют делиться видео в реальном времени с одной вкладки браузера или со всего рабочего стола через API chrome.tabCapture
и chrome.desktopCapture
. (Демонстрацию и дополнительную информацию см. в статье «Демонстрация экрана с помощью WebRTC» . Эта статья устарела на несколько лет, но она всё ещё интересна.)
В Chrome также можно использовать функцию захвата экрана в качестве источника MediaStream
с помощью экспериментального ограничения chromeMediaSource
. Обратите внимание, что для захвата экрана требуется HTTPS, и его следует использовать только в целях разработки, поскольку он включается с помощью флага командной строки, как описано в этой статье .
Сигнализация: управление сеансом, сеть и медиа-информация
WebRTC использует RTCPeerConnection
для передачи потоковых данных между браузерами (также известными как пиры), но также нуждается в механизме координации обмена данными и отправки управляющих сообщений — процессе, известном как сигнализация. Методы и протоколы сигнализации не определены в WebRTC. Сигнализация не является частью API RTCPeerConnection
.
Вместо этого разработчики приложений WebRTC могут выбрать любой предпочитаемый ими протокол обмена сообщениями, например SIP или XMPP, и любой подходящий дуплексный (двусторонний) канал связи. В примере appr.tc в качестве сигнального механизма используются XHR и API Channel. В практической работе используется Socket.io , работающий на сервере Node .
Сигнализация используется для обмена тремя типами информации:
- Сообщения управления сеансом: для инициализации или закрытия связи и сообщения об ошибках.
- Конфигурация сети: какой IP-адрес и порт вашего компьютера для внешнего мира?
- Возможности мультимедиа: какие кодеки и разрешения поддерживает ваш браузер и браузер, с которым он хочет взаимодействовать?
Обмен информацией посредством сигнализации должен быть успешно завершен, прежде чем начнется одноранговая потоковая передача.
Например, представьте, что Алиса хочет связаться с Бобом. Вот пример кода из спецификации W3C WebRTC , демонстрирующий процесс сигнализации в действии. Код предполагает наличие некоего механизма сигнализации, созданного в методе createSignalingChannel()
. Также обратите внимание, что в Chrome и Opera в настоящее время используется префикс RTCPeerConnection
.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// Send the offer to the other peer.
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
Сначала Алиса и Боб обмениваются сетевой информацией. (Выражение «поиск кандидатов» относится к процессу поиска сетевых интерфейсов и портов с использованием фреймворка ICE.)
- Алиса создает объект
RTCPeerConnection
с обработчикомonicecandidate
, который запускается, когда сетевые кандидаты становятся доступными. - Алиса отправляет сериализованные данные о кандидатах Бобу через любой используемый ими канал сигнализации, например WebSocket или какой-либо другой механизм.
- Когда Боб получает сообщение о кандидате от Алисы, он вызывает
addIceCandidate
, чтобы добавить кандидата в описание удаленного однорангового узла.
Клиенты WebRTC (также известные как пиры , или Алиса и Боб в данном примере) также должны получать и обмениваться локальной и удалённой аудио- и видеоинформацией, такой как разрешение и возможности кодеков. Сигнализация для обмена информацией о конфигурации медиаданных осуществляется путём обмена предложением и ответом с использованием протокола описания сеанса (SDP):
- Алиса запускает метод
RTCPeerConnection
createOffer()
. Возвращаемое им значение передаётся вRTCSessionDescription
— описание локального сеанса Алисы. - В обратном вызове Алиса устанавливает локальное описание с помощью
setLocalDescription()
, а затем отправляет это описание сеанса Бобу по его сигнальному каналу. Обратите внимание, чтоRTCPeerConnection
не начнёт сбор кандидатов, пока не будет вызванsetLocalDescription()
. Это регламентировано в проекте JSEP IETF . - Боб устанавливает описание, которое Алиса отправила ему, в качестве удаленного описания с помощью
setRemoteDescription()
. - Боб запускает метод
RTCPeerConnection
createAnswer()
, передавая ему удалённое описание, полученное от Алисы, чтобы создать локальный сеанс, совместимый с её сеансом. Обратному вызовуcreateAnswer()
передаётсяRTCSessionDescription
. Боб устанавливает его в качестве локального описания и отправляет Алисе. - Когда Алиса получает описание сеанса Боба, она устанавливает его как удаленное описание с помощью
setRemoteDescription
. - Пинг!
Объекты RTCSessionDescription
— это двоичные объекты, соответствующие протоколу описания сеансов (SDP). Сериализованный объект SDP выглядит следующим образом:
v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126
// ...
a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810
Получение и обмен сетевой и медиаинформацией могут осуществляться одновременно, но оба процесса должны быть завершены до начала потоковой передачи аудио- и видеоданных между одноранговыми узлами.
Описанная ранее архитектура «предложение/ответ» называется протоколом установления сеанса JavaScript , или JSEP. (В демонстрационном видеоролике Ericsson для первой реализации WebRTC есть прекрасная анимация, поясняющая процесс сигнализации и потоковой передачи.)

После успешного завершения процесса сигнализации данные могут передаваться напрямую по одноранговой сети между вызывающим и вызываемым абонентами, или, в случае неудачи, через промежуточный сервер-ретранслятор (подробнее об этом позже). Потоковая передача данных — это задача RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
— это компонент WebRTC, который обеспечивает стабильную и эффективную передачу потоковых данных между одноранговыми узлами.
Ниже представлена схема архитектуры WebRTC, демонстрирующая роль RTCPeerConnection
. Как вы можете заметить, зелёные элементы — сложные!

С точки зрения JavaScript, главное, что нужно понять из этой диаграммы, — это то, что RTCPeerConnection
защищает веб-разработчиков от множества скрытых сложностей. Кодеки и протоколы, используемые WebRTC, выполняют огромную работу, обеспечивая возможность общения в режиме реального времени, даже в ненадежных сетях:
- Скрытие потери пакетов
- Эхоподавление
- Адаптивность полосы пропускания
- Динамическая буферизация джиттера
- Автоматическая регулировка усиления
- Шумоподавление и подавление
- Очистка изображения
Предыдущий код W3C демонстрирует упрощённый пример WebRTC с точки зрения сигнализации. Ниже приведены пошаговые инструкции по двум работающим приложениям WebRTC. Первое — простой пример для демонстрации RTCPeerConnection
, а второе — полнофункциональный клиент видеочата.
RTCPeerConnection без серверов
Следующий код взят из примера WebRTC Peer Connection , где на одной веб-странице есть локальный и удалённый RTCPeerConnection
(а также локальное и удалённое видео). Это не представляет особой пользы — вызывающий и вызываемый объекты находятся на одной странице, — но делает работу API RTCPeerConnection
немного понятнее, поскольку объекты RTCPeerConnection
на странице могут обмениваться данными и сообщениями напрямую, без использования промежуточных механизмов сигнализации.
В этом примере pc1
представляет локальный одноранговый узел (вызывающий), а pc2
представляет удаленный одноранговый узел (вызываемый).
Звонящий
- Создайте новый
RTCPeerConnection
и добавьте поток изgetUserMedia()
: ```js // Servers — необязательный файл конфигурации. (См. обсуждение TURN и STUN далее.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- Создайте предложение и установите его как локальное описание для
pc1
и как удалённое описание дляpc2
. Это можно сделать непосредственно в коде без использования сигнализации, поскольку и вызывающий, и вызываемый объекты находятся на одной странице:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
Вызываемый
- Создайте
pc2
и, когда поток сpc1
будет добавлен, отобразите его в элементе видео:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
API RTCPeerConnection
плюс серверы
В реальном мире WebRTC нуждается в серверах, какими бы простыми они ни были, поэтому может произойти следующее:
- Пользователи находят друг друга и обмениваются реальными данными, такими как имена.
- Клиентские приложения WebRTC (одноранговые узлы) обмениваются сетевой информацией.
- Участники обмениваются данными о медиаресурсах, такими как формат и разрешение видео.
- Клиентские приложения WebRTC обходят шлюзы NAT и брандмауэры.
Другими словами, WebRTC нуждается в четырех типах серверной функциональности:
- Обнаружение и коммуникация пользователей
- Сигнализация
- Обход NAT/брандмауэра
- Ретрансляционные серверы на случай сбоя одноранговой связи
Обход NAT, одноранговые сети и требования к созданию серверного приложения для обнаружения пользователей и сигнализации выходят за рамки данной статьи. Достаточно сказать, что протокол STUN и его расширение TURN используются фреймворком ICE для того, чтобы RTCPeerConnection
мог справляться с обходом NAT и другими особенностями сети.
ICE — это фреймворк для соединения одноранговых узлов, например, двух клиентов видеочата. Изначально ICE пытается соединить одноранговые узлы напрямую с минимально возможной задержкой по протоколу UDP. В этом процессе у STUN-серверов есть одна задача: предоставить одноранговому узлу за NAT возможность узнать свой публичный адрес и порт. (Подробнее о STUN и TURN см. в разделе «Создание внутренних служб, необходимых для приложения WebRTC »).

Если UDP-соединение не работает, ICE пытается использовать TCP. Если прямое соединение не удаётся, в частности, из-за обхода NAT и межсетевых экранов, ICE использует промежуточный (ретрансляционный) TURN-сервер. Другими словами, ICE сначала использует STUN с UDP для прямого подключения одноранговых узлов, а в случае неудачи возвращается к ретрансляционному TURN-серверу. Выражение «поиск кандидатов» относится к процессу поиска сетевых интерфейсов и портов.

Инженер WebRTC Джастин Уберти представил более подробную информацию об ICE, STUN и TURN в презентации WebRTC на конференции Google I/O 2013 года . ( На слайдах презентации приведены примеры реализаций серверов TURN и STUN.)
Простой клиент видеочата
Хорошим местом для знакомства с WebRTC, включая сигнализацию и обход NAT/брандмауэра с помощью STUN-сервера, является демонстрация видеочата на appr.tc. Это приложение использует adapter.js — промежуточную версию для защиты приложений от изменений спецификаций и различий в префиксах.
Код намеренно содержит много информации в логах. Проверьте консоль, чтобы понять порядок событий. Ниже представлен подробный разбор кода.
Сетевые топологии
WebRTC в его текущей реализации поддерживает только связь «один к одному», но может использоваться в более сложных сетевых сценариях, например, когда несколько одноранговых узлов взаимодействуют друг с другом напрямую или через многоточечный блок управления (MCU) — сервер, который может обрабатывать большое количество участников и выполнять выборочную пересылку потоков, а также микширование или запись аудио и видео.

Многие существующие приложения WebRTC обеспечивают взаимодействие только между веб-браузерами, но серверы шлюзов могут позволить приложению WebRTC, работающему в браузере, взаимодействовать с устройствами, такими как телефоны (также известные как PSTN ), и с системами VoIP . В мае 2012 года компания Doubango Telecom открыла исходный код SIP-клиента sipml5, созданного с использованием WebRTC и WebSocket, который (среди других потенциальных применений) позволяет осуществлять видеозвонки между браузерами и приложениями на iOS и Android. На конференции Google I/O компании Tethr и Tropo продемонстрировали фреймворк для организации связи в случае стихийных бедствий в портфеле, используя ячейку OpenBTS для обеспечения связи между обычными телефонами и компьютерами через WebRTC. Телефонная связь без оператора!

API RTCDataChannel
<
Помимо аудио и видео, WebRTC поддерживает передачу других типов данных в реальном времени.
API RTCDataChannel
обеспечивает одноранговый обмен произвольными данными с малой задержкой и высокой пропускной способностью. Для просмотра одностраничных демонстраций и создания простого приложения для передачи файлов см. примеры WebRTC и практическую работу WebRTC соответственно.
Существует множество потенциальных вариантов использования API, включая:
- Игры
- Приложения для удаленного рабочего стола
- Текстовый чат в реальном времени
- Передача файлов
- Децентрализованные сети
API имеет несколько функций, которые позволяют максимально эффективно использовать RTCPeerConnection
и обеспечивают мощную и гибкую одноранговую связь:
- Использование настройки сеанса
RTCPeerConnection
- Несколько одновременных каналов с приоритизацией
- Надежная и ненадежная семантика доставки
- Встроенная безопасность (DTLS) и контроль перегрузки
- Возможность использования с аудио или видео или без них
Синтаксис намеренно похож на WebSocket с методом send()
и событием message
:
const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
localConnection.createDataChannel('sendDataChannel');
// ...
remoteConnection.ondatachannel = (event) => {
receiveChannel = event.channel;
receiveChannel.onmessage = onReceiveMessage;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
};
function onReceiveMessage(event) {
document.querySelector("textarea#send").value = event.data;
}
document.querySelector("button#send").onclick = () => {
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
};
Связь осуществляется напрямую между браузерами, поэтому RTCDataChannel
может быть намного быстрее, чем WebSocket, даже если требуется ретрансляционный (TURN) сервер, когда попытки преодолеть брандмауэры и NAT не удаются.
RTCDataChannel
доступен в Chrome, Safari, Firefox, Opera и Samsung Internet. Игра Cube Slam использует API для передачи данных о состоянии игры. Играйте с другом или играйте с медведем! Инновационная платформа Sharefest обеспечила обмен файлами через RTCDataChannel
и peerCDN , продемонстрировав, как WebRTC может обеспечить одноранговое распространение контента.
Для получения дополнительной информации о RTCDataChannel
ознакомьтесь с проектом спецификации протокола IETF.
Безопасность
Приложение или плагин для общения в режиме реального времени может поставить под угрозу безопасность несколькими способами. Например:
- Незашифрованные медиафайлы или данные могут быть перехвачены между браузерами или между браузером и сервером.
- Приложение может записывать и распространять видео или аудио без ведома пользователя.
- Вредоносное ПО или вирусы могут быть установлены вместе с, на первый взгляд, безобидным плагином или приложением.
WebRTC имеет несколько функций, позволяющих избежать этих проблем:
- Реализации WebRTC используют безопасные протоколы, такие как DTLS и SRTP .
- Шифрование обязательно для всех компонентов WebRTC, включая механизмы сигнализации.
- WebRTC не является плагином. Его компоненты работают в «песочнице» браузера, а не в отдельном процессе. Компоненты не требуют отдельной установки и обновляются при каждом обновлении браузера.
- Доступ к камере и микрофону должен быть предоставлен явно, и когда камера или микрофон работают, это четко отображается в пользовательском интерфейсе.
Подробное обсуждение вопросов безопасности потокового мультимедиа выходит за рамки этой статьи. Подробнее см. в документе «Предлагаемая архитектура безопасности WebRTC», предложенном IETF.
В заключение
API и стандарты WebRTC могут демократизировать и децентрализовать инструменты для создания контента и коммуникации, включая телефонию, игры, видеопроизводство, создание музыки и сбор новостей.
Более разрушительных технологий уже не существует.
Как выразился блогер Фил Эдхольм: «Потенциально WebRTC и HTML5 могли бы обеспечить такое же преобразование для общения в реальном времени, какое оригинальный браузер делал для информации».
Инструменты разработчика
- Статистику WebRTC для текущего сеанса можно найти по адресу:
- about://webrtc-internals в Chrome
- opera://webrtc-internals в Opera
- about:webrtc в Firefox
скриншот chrome://webrtc-internals
- Примечания к кросс-браузерному взаимодействию
- adapter.js — это JavaScript-оболочка для WebRTC, поддерживаемая Google при помощи сообщества WebRTC , которая абстрагирует префиксы поставщиков, различия браузеров и изменения спецификаций.
- Чтобы узнать больше о процессах сигнализации WebRTC, проверьте вывод журнала appr.tc на консоль.
- Если этого слишком много, вы можете предпочесть использовать фреймворк WebRTC или даже полноценный сервис WebRTC .
- Сообщения об ошибках и предложения по функциям всегда приветствуются:
Узнать больше
- Сессия Джастина Уберти по WebRTC на Google I/O 2012
- Алан Б. Джонстон и Дэниел К. Бернетт поддерживают третье издание книги по WebRTC в печатном и электронном форматах на сайте webrtcbook.com .
- webrtc.org — это место, где собрано все, что касается WebRTC, включая демонстрации, документацию и обсуждения.
- discussion-webrtc — это группа Google для технических обсуждений WebRTC.
- @webrtc
- Документация Google Developers Talk содержит дополнительную информацию о прохождении NAT, STUN, серверах ретрансляции и сборе кандидатов.
- WebRTC на GitHub
- Stack Overflow — хорошее место для поиска ответов и вопросов о WebRTC.
Стандарты и протоколы
- Редакторский проект WebRTC W3C
- Редакторский проект W3C: Захват мультимедиа и потоки (также известный как
getUserMedia
) - Устав рабочей группы IETF
- Проект протокола канала данных IETF WebRTC
- Проект IETF JSEP
- Предложенный IETF стандарт для ICE
- Интернет-проект рабочей группы IETF RTCWEB: Примеры использования и требования к веб-коммуникациям в реальном времени
Обзор поддержки WebRTC
API MediaStream
и getUserMedia
- Chrome для ПК 18.0.1008 и выше; Chrome для Android 29 и выше
- Opera 18 и выше; Opera для Android 20 и выше
- Opera 12, Opera Mobile 12 (на базе движка Presto)
- Firefox 17 и выше
- Microsoft Edge 16 и выше
- Safari 11.2 и выше на iOS и 11.1 и выше на macOS
- UC 11.8 и выше на Android
- Samsung Internet 4 и выше
API RTCPeerConnection
- Chrome для ПК версии 20 и выше; Chrome для Android версии 29 и выше (без флагов)
- Opera 18 и выше (включено по умолчанию); Opera для Android 20 и выше (включено по умолчанию)
- Firefox 22 и выше (включено по умолчанию)
- Microsoft Edge 16 и выше
- Safari 11.2 и выше на iOS и 11.1 и выше на macOS
- Samsung Internet 4 и выше
API RTCDataChannel
- Экспериментальная версия в Chrome 25, но более стабильная (и совместимая с Firefox) в Chrome 26 и выше; Chrome для Android 29 и выше
- Стабильная версия (совместимая с Firefox) в Opera 18 и выше; Opera для Android 20 и выше
- Firefox 22 и выше (включено по умолчанию)
Более подробную информацию о кроссплатформенной поддержке API, таких как getUserMedia
и RTCPeerConnection
, см. на сайтах caniuse.com и Chrome Platform Status .
Собственные API для RTCPeerConnection
также доступны в документации на webrtc.org .