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

WebRTC — это новый фронт в долгой войне за открытый и свободный Интернет.

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

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

Представьте себе мир, в котором ваш телефон, телевизор и компьютер могут взаимодействовать на общей платформе. Представьте, что добавить видеочат и обмен данными по сети P2P в ваше веб-приложение стало легко. В этом и заключается концепция 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 ) - 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 — это взглянуть на него вживую:

  1. В браузере перейдите к примерам WebRTC getUserMedia .
  2. Откройте консоль.
  3. Проверьте переменную 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.
Изображение ASCII, созданное idevelop.ro/ascii-camera
GUM 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.)

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

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

  1. Алиса запускает метод RTCPeerConnection createOffer() . Возвращаемое им значение передаётся в RTCSessionDescription — описание локального сеанса Алисы.
  2. В обратном вызове Алиса устанавливает локальное описание с помощью setLocalDescription() , а затем отправляет это описание сеанса Бобу по его сигнальному каналу. Обратите внимание, что RTCPeerConnection не начнёт сбор кандидатов, пока не будет вызван setLocalDescription() . Это регламентировано в проекте JSEP IETF .
  3. Боб устанавливает описание, которое Алиса отправила ему, в качестве удаленного описания с помощью setRemoteDescription() .
  4. Боб запускает метод RTCPeerConnection createAnswer() , передавая ему удалённое описание, полученное от Алисы, чтобы создать локальный сеанс, совместимый с её сеансом. Обратному вызову 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 // Servers — необязательный файл конфигурации. (См. обсуждение 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 );

Вызываемый

  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 в презентации 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. Телефонная связь без оператора!

Демонстрация 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 и выше
  • 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 .