Начните работу с WebRTC

WebRTC — это новый фронт в долгой войне за открытую и ничем не обремененную сеть.

Брендан Эйх, изобретатель JavaScript

Общение в режиме реального времени без плагинов

Представьте себе мир, в котором ваш телефон, телевизор и компьютер могут обмениваться данными на общей платформе. Представьте, что в ваше веб-приложение было легко добавить видеочат и одноранговый обмен данными. Это видение WebRTC.

Хотите попробовать? WebRTC доступен на настольных компьютерах и мобильных устройствах в Google Chrome, Safari, Firefox и Opera. Хорошее место для начала — простое приложение для видеочата по адресу appr.tc :

  1. Откройте appr.tc в своем браузере.
  2. Нажмите «Присоединиться» , чтобы присоединиться к чату и разрешить приложению использовать вашу веб-камеру.
  3. Откройте URL-адрес, отображаемый в конце страницы, в новой вкладке или, еще лучше, на другом компьютере.

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

У вас нет времени читать эту статью или вам нужен только код?

Альтернативный вариант — сразу перейти к лаборатории кода 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 ) — RTCPeerConnectionRTCDataChannel

API определены в этих двух спецификациях:

Все три API поддерживаются на мобильных устройствах и настольных компьютерах Chrome, Safari, Firefox, Edge и Opera.

getUserMedia : демонстрационные версии и код см. в примерах WebRTC или попробуйте удивительные примеры Криса Уилсона, в которых getUserMedia используется в качестве входных данных для веб-аудио.

RTCPeerConnection : для простой демонстрации и полнофункционального приложения для видеочата см. примеры WebRTC Peer Connection и appr.tc соответственно. В этом приложении используется адаптер.js , оболочка JavaScript, поддерживаемая Google при помощи сообщества WebRTC , для абстрагирования различий между браузерами и изменений спецификаций.

RTCDataChannel : Чтобы увидеть это в действии, посмотрите примеры WebRTC, чтобы проверить одну из демонстраций канала данных.

В лаборатории кода WebRTC показано, как использовать все три API для создания простого приложения для видеочата и обмена файлами.

Ваш первый WebRTC

Приложения WebRTC должны делать несколько вещей:

  • Получите потоковое аудио, видео или другие данные.
  • Получайте сетевую информацию, такую ​​как IP-адреса и порты, и обменивайтесь ею с другими клиентами WebRTC (известными как одноранговые узлы ), чтобы обеспечить соединение даже через NAT и брандмауэры.
  • Координируйте сигнальную связь, чтобы сообщать об ошибках и инициировать или закрывать сеансы.
  • Обменивайтесь информацией о возможностях мультимедиа и клиента, таких как разрешение и кодеки.
  • Обменивайтесь потоковым аудио, видео или данными.

Для получения и передачи потоковых данных WebRTC реализует следующие API:

  • MediaStream получает доступ к потокам данных, например, с камеры и микрофона пользователя.
  • RTCPeerConnection обеспечивает аудио- или видеовызовы с возможностью шифрования и управления полосой пропускания.
  • RTCDataChannel обеспечивает одноранговую передачу общих данных.

(Подробное обсуждение сетевых и сигнальных аспектов WebRTC будет рассмотрено позже.)

MediaStream API (также известный как getUserMedia API)

API MediaStream представляет синхронизированные потоки мультимедиа. Например, поток, поступающий со входа камеры и микрофона, синхронизирует видео и аудио дорожки. (Не путайте MediaStreamTrack с элементом <track> , это нечто совершенно другое .)

Вероятно, самый простой способ понять API MediaStream — посмотреть на него в реальных условиях:

  1. В браузере перейдите к примерам WebRTC getUserMedia .
  2. Откройте консоль.
  3. Проверьте переменную stream , которая находится в глобальной области видимости.

Каждый MediaStream имеет вход, который может быть MediaStream , сгенерированный getUserMedia() , и выход, который может быть передан в элемент видео или RTCPeerConnection .

Метод getUserMedia() принимает параметр объекта MediaStreamConstraints и возвращает Promise , который разрешается в объект MediaStream .

Каждый MediaStream имеет label , например 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ' . Массив MediaStreamTrack возвращается методами getAudioTracks() и getVideoTracks() .

В примере 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() действительно оживает в сочетании с другими API и библиотеками JavaScript:

  • Webcam Toy — это приложение для фотокабины, которое использует WebGL для добавления странных и замечательных эффектов к фотографиям, которыми можно поделиться или сохранить локально.
  • FaceKat — это игра для отслеживания лиц, созданная с помощью headtrackr.js .
  • ASCII Camera использует Canvas API для создания изображений ASCII.
Изображение ASCII, созданное idevelop.ro/ascii-camera
ГУМ ASCII-арт!

Ограничения

Ограничения можно использовать для установки значений разрешения видео для getUserMedia() . Это также обеспечивает поддержку других ограничений , таких как соотношение сторон; режим лицом (передняя или задняя камера); частота кадров, высота и ширина; и метод applyConstraints() .

Пример см. в примерах WebRTC getUserMedia : выберите разрешение .

Установка недопустимого значения ограничения приводит к возникновению DOMException или OverconstrainedError , если, например, запрошенное разрешение недоступно. Чтобы увидеть это в действии, посмотрите примеры WebRTC. getUserMedia : выберите разрешение для демонстрации.

Захват экрана и вкладок

Приложения Chrome также позволяют делиться живым видео одной вкладки браузера или всего рабочего стола через API chrome.tabCapture и chrome.desktopCapture . (Демо-версию и дополнительную информацию см. в разделе «Совместное использование экрана с помощью WebRTC» . Статье уже несколько лет, но она по-прежнему интересна.)

Также можно использовать снимок экрана в качестве источника MediaStream в Chrome, используя экспериментальное ограничение chromeMediaSource . Обратите внимание, что для захвата экрана требуется HTTPS, и его следует использовать только для разработки, поскольку он включается с помощью флага командной строки, как описано в этом посте .

Сигнализация: управление сеансом, информация о сети и мультимедиа.

WebRTC использует RTCPeerConnection для передачи потоковых данных между браузерами (также известными как одноранговые узлы), но ему также необходим механизм для координации связи и отправки управляющих сообщений — процесс, известный как сигнализация. Методы и протоколы сигнализации не указаны в WebRTC. Сигнализация не является частью API RTCPeerConnection .

Вместо этого разработчики приложений WebRTC могут выбрать любой протокол обмена сообщениями, который они предпочитают, например SIP или XMPP, и любой подходящий дуплексный (двусторонний) канал связи. В примере appr.tc в качестве механизма сигнализации используется XHR и Channel API. В кодовой лаборатории используется 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.)

  1. Алиса создает объект RTCPeerConnection с обработчиком onicecandidate , который запускается, когда сетевые кандидаты становятся доступными.
  2. Алиса отправляет Бобу сериализованные данные-кандидаты через любой канал сигнализации, который они используют, например WebSocket или какой-либо другой механизм.
  3. Когда Боб получает сообщение о кандидате от Алисы, он вызывает addIceCandidate , чтобы добавить кандидата в описание удаленного узла.

Клиентам WebRTC (также известным как одноранговые узлы или в этом примере Алиса и Боб) также необходимо проверять и обмениваться локальной и удаленной аудио- и видеоинформацией, такой как разрешение и возможности кодека. Сигнализация для обмена информацией о конфигурации носителя происходит путем обмена предложением и ответом с использованием протокола описания сеанса (SDP):

  1. Алиса запускает метод createOffer() RTCPeerConnection . В ответ передается RTCSessionDescription — описание локального сеанса Алисы.
  2. В обратном вызове Алиса устанавливает локальное описание с помощью setLocalDescription() , а затем отправляет это описание сеанса Бобу через его сигнальный канал. Обратите внимание, что RTCPeerConnection не начнет собирать кандидатов до тех пор, пока не будет вызвана setLocalDescription() . Это кодифицировано в проекте JSEP IETF .
  3. Боб устанавливает описание, отправленное ему Алисой, в качестве удаленного описания, используя setRemoteDescription() .
  4. Боб запускает метод createAnswer() RTCPeerConnection , передавая ему удаленное описание, полученное от Алисы, чтобы можно было сгенерировать локальный сеанс, совместимый с ее сеансом. Обратному вызову createAnswer() передается RTCSessionDescription . Боб устанавливает это как локальное описание и отправляет Алисе.
  5. Когда Алиса получает описание сеанса Боба, она устанавливает его как удаленное описание с помощью setRemoteDescription .
  6. Пинг!

Объекты 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, есть отличная анимация, объясняющая процесс передачи сигналов и потоковой передачи.)

Схема архитектуры JSEP
JSEP-архитектура

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

RTCPeerConnection

RTCPeerConnection — это компонент WebRTC, который обеспечивает стабильную и эффективную передачу потоковых данных между узлами.

Ниже представлена ​​схема архитектуры WebRTC, показывающая роль RTCPeerConnection . Как вы заметили, зеленые части сложны!

Схема архитектуры WebRTC
Архитектура WebRTC (с сайта webrtc.org )

С точки зрения JavaScript, из этой диаграммы следует понять, что RTCPeerConnection защищает веб-разработчиков от множества сложностей, которые скрываются под ним. Кодеки и протоколы, используемые WebRTC, выполняют огромную работу, чтобы сделать возможным общение в реальном времени, даже в ненадежных сетях:

  • Сокрытие потери пакетов
  • Эхоподавление
  • Адаптивность полосы пропускания
  • Динамическая буферизация джиттера
  • Автоматическая регулировка усиления
  • Снижение и подавление шума
  • Очистка изображений

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

RTCPeerConnection без серверов

Следующий код взят из примеров WebRTC Peer Connection , который имеет локальное и удаленное RTCPeerConnection (а также локальное и удаленное видео) на одной веб-странице. Это не представляет собой ничего особенно полезного — вызывающая сторона и вызываемая сторона находятся на одной странице — но это делает работу API RTCPeerConnection немного более понятной, поскольку объекты RTCPeerConnection на странице могут обмениваться данными и сообщениями напрямую, без необходимости использования промежуточной сигнализации. механизмы.

В этом примере pc1 представляет локальный узел (вызывающий абонент), а pc2 представляет удаленный узел (вызываемый абонент).

Звонящий

  1. Создайте новое RTCPeerConnection и добавьте поток из getUserMedia() : ```js // Серверы — это необязательный файл конфигурации. (См. обсуждение TURN и STUN ниже.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
  1. Создайте предложение и установите его в качестве локального описания для pc1 и удаленного описания для pc2 . Это можно сделать непосредственно в коде без использования сигнализации, поскольку и вызывающая сторона, и вызываемая сторона находятся на одной странице: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

Callee

  1. Создайте 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
Пути передачи данных WebRTC

Инженер WebRTC Джастин Уберти предоставляет дополнительную информацию о ICE, STUN и TURN в презентации Google I/O WebRTC 2013 года . ( На слайдах презентации приведены примеры реализации серверов TURN и STUN.)

Простой клиент видеочата

Хорошим местом, чтобы попробовать WebRTC, дополненный сигнализацией и обходом NAT/брандмауэра с использованием сервера STUN, является демонстрация видеочата на appr.tc. Это приложение использует адаптер.js — прокладку, которая изолирует приложения от изменений спецификаций и различий в префиксах.

Код намеренно многословен при протоколировании. Проверьте консоль, чтобы понять порядок событий. Ниже приводится подробное описание кода.

Топологии сети

WebRTC, реализованный в настоящее время, поддерживает только связь «один к одному», но может использоваться в более сложных сетевых сценариях, например, когда несколько узлов взаимодействуют друг с другом напрямую или через многоточечный блок управления (MCU), сервер, который может обрабатывать большое количество участников и выполнять выборочную пересылку потоков, а также микширование или запись аудио и видео.

Схема топологии многоточечного блока управления
Пример топологии многоточечного блока управления

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

Демонстрация Tethr/Tropo на Google I/O 2012
Tethr/Tropo: средства связи при стихийных бедствиях в портфеле

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

API MediaStream и getUserMedia

  • Рабочий стол Chrome 18.0.1008 и выше; Chrome для Android 29 и выше
  • Опера 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 Интернет 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 Интернет 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 .

Собственные API для RTCPeerConnection также доступны в документации на webrtc.org .