Отправляйте данные между браузерами с помощью каналов данных WebRTC.

Отправка данных между двумя браузерами для общения, игр или передачи файлов может быть довольно сложным процессом. Это требует настройки и оплаты сервера для ретрансляции данных и, возможно, его масштабирования на несколько центров обработки данных. В этом сценарии существует вероятность высокой задержки и сложно обеспечить конфиденциальность данных.

Эти проблемы можно решить, используя API RTCDataChannel WebRTC для передачи данных напрямую от одного узла к другому. В этой статье рассматриваются основы настройки и использования каналов передачи данных, а также распространенные варианты использования в Интернете сегодня.

Зачем еще один канал данных?

У нас есть WebSocket , AJAX и события, отправленные сервером . Зачем нам нужен еще один канал связи? WebSocket является двунаправленным, но все эти технологии предназначены для связи с сервером или с ним.

RTCDataChannel использует другой подход:

  • Он работает с API RTCPeerConnection , который обеспечивает одноранговое соединение. Это может привести к снижению задержки — отсутствие промежуточного сервера и меньшее количество «прыжков».
  • RTCDataChannel использует протокол передачи управления потоком (SCTP), позволяющий настраивать семантику доставки, доставку вне очереди и повторную передачу конфигурации.

RTCDataChannel теперь доступен с поддержкой SCTP на настольных компьютерах и Android в Google Chrome, Opera и Firefox.

Предостережение: сигнализация, оглушение и поворот.

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

WebRTC справляется с NAT и межсетевыми экранами с помощью:

  • Структура ICE для установления наилучшего сетевого пути между узлами.
  • Серверы STUN для определения общедоступного IP-адреса и порта для каждого узла.
  • TURN-серверы , если прямое соединение не установлено и требуется ретрансляция данных.

Дополнительные сведения о том, как WebRTC работает с серверами для сигнализации и работы в сети, см. в разделе WebRTC в реальном мире: STUN, TURN и сигнализация .

Возможности

API RTCDataChannel поддерживает гибкий набор типов данных. API разработан для точной имитации WebSocket, а RTCDataChannel поддерживает строки , а также некоторые двоичные типы в JavaScript, такие как Blob , ArrayBuffer и ArrayBufferView . Эти типы могут быть полезны при работе с передачей файлов и многопользовательскими играми.

RTCDataChannel может работать в ненадежном и неупорядоченном режиме (аналоге протокола пользовательских датаграмм или UDP), надежном и упорядоченном режиме (аналоге протокола управления передачей или TCP) и частично надежных режимах:

  • Надежный и упорядоченный режим гарантирует передачу сообщений, а также порядок их доставки . Это требует дополнительных затрат, что потенциально может замедлить работу этого режима.
  • Ненадежный и неупорядоченный режим не гарантирует, что все сообщения дойдут до другой стороны и в каком порядке они туда доберутся . Это устраняет накладные расходы, позволяя этому режиму работать намного быстрее.
  • Режим частичной надежности гарантирует передачу сообщения при определенных условиях, таких как тайм-аут повторной передачи или максимальное количество повторных передач . Порядок сообщений также настраивается.

Производительность для первых двух режимов примерно одинакова при отсутствии потерь пакетов. Однако в надежном и упорядоченном режиме потерянный пакет приводит к блокировке других пакетов за ним, и потерянный пакет может оказаться устаревшим к моменту его повторной передачи и прибытия. Конечно, можно использовать несколько каналов данных в одном приложении, каждый из которых имеет свою надежную или ненадежную семантику.

Вот полезная таблица из книги «Высокопроизводительная браузерная сеть» Ильи Григорика :

TCP UDP SCTP
Надежность Надежный Ненадежный Настраиваемый
Доставка Заказал Неупорядоченный Настраиваемый
Передача инфекции Байт-ориентированный Ориентированный на сообщения Ориентированный на сообщения
Управление потоком Да Нет Да
Контроль перегрузок Да Нет Да

Далее вы узнаете, как настроить RTCDataChannel для использования надежного и упорядоченного или ненадежного и неупорядоченного режима.

Настройка каналов передачи данных

В Интернете есть несколько простых демонстраций RTCDataChannel :

В этих примерах браузер устанавливает одноранговое соединение с самим собой, затем создает канал данных и отправляет сообщение через одноранговое соединение. Затем он создает канал данных и отправляет сообщение по одноранговому соединению. Наконец, ваше сообщение появится в поле на другой стороне страницы!

Код для начала работы короткий:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

Объект dataChannel создается на основе уже установленного однорангового соединения. Его можно создать до или после передачи сигнала. Затем вы передаете метку, позволяющую отличить этот канал от других, и набор дополнительных параметров конфигурации:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

Также можно добавить параметр maxRetransmits (количество попыток до сбоя), но вы можете указать только maxRetransmits или maxPacketLifeTime, а не оба. Для семантики UDP установите maxRetransmits в 0 и ordered значение false . Дополнительные сведения см. в документах IETF RFC: Протокол передачи управления потоком и Расширение частичной надежности протокола передачи управления потоком .

  • ordered : должен ли канал данных гарантировать порядок или нет
  • maxPacketLifeTime : максимальное время для попытки повторной передачи неудачного сообщения.
  • maxRetransmits : максимальное количество попыток повторной передачи неудачного сообщения.
  • protocol : позволяет использовать подпротокол, который предоставляет метаинформацию приложению.
  • negotiated : если установлено значение true, отменяется автоматическая настройка канала данных на другом узле, предоставляя собственный способ создания канала данных с тем же идентификатором на другой стороне.
  • id : позволяет вам указать свой собственный идентификатор для канала, который можно использовать только в сочетании с negotiated значением true )

Единственные параметры, которые необходимо использовать большинству людей, — это первые три: ordered , maxPacketLifeTime и maxRetransmits . С SCTP (сейчас используется всеми браузерами, поддерживающими WebRTC) надежность и упорядоченность верны по умолчанию. Имеет смысл использовать unreliable и unordered, если вам нужен полный контроль с уровня приложения, но в большинстве случаев частичная надежность полезна.

Обратите внимание, что, как и в случае с WebSocket, RTCDataChannel генерирует события, когда соединение устанавливается, закрывается или возникает ошибка, а также когда он получает сообщение от другого узла.

Это безопасно?

Шифрование является обязательным для всех компонентов WebRTC. При использовании RTCDataChannel все данные защищены с помощью Datagram Transport Layer Security (DTLS). DTLS — это производная от SSL, что означает, что ваши данные будут так же безопасны, как и при использовании любого стандартного соединения на основе SSL. DTLS стандартизирован и встроен во все браузеры, поддерживающие WebRTC. Для получения дополнительной информации см. Wiki Wireshark .

Измените свое отношение к данным

Обработка больших объемов данных может стать болевой точкой в ​​JavaScript. Как отметили разработчики Sharefest , это потребовало по-новому взглянуть на данные. Если вы передаете файл, размер которого превышает объем доступной вам памяти, вам придется подумать о новых способах сохранения этой информации. Как вы увидите далее, именно здесь в игру вступают такие технологии, как FileSystem API .

Создайте приложение для обмена файлами

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

Для успешного перевода необходимо выполнить несколько шагов:

  1. Прочтите файл в JavaScript с помощью File API .
  2. Установите одноранговое соединение между клиентами с помощью RTCPeerConnection .
  3. Создайте канал данных между клиентами с помощью RTCDataChannel .

При отправке файлов через RTCDataChannel следует учитывать несколько моментов:

  • Размер файла: если размер файла достаточно мал и может храниться и загружаться как один большой двоичный объект, вы можете загрузить его в память с помощью File API, а затем отправить файл по надежному каналу как есть (хотя имейте в виду, что браузеры накладывают ограничения на максимальный размер файла). размер перевода). По мере увеличения размера файла все становится сложнее. Когда требуется механизм фрагментирования, фрагменты файлов загружаются и отправляются другому узлу вместе с метаданными chunkID , чтобы узел мог их распознать. Обратите внимание, что в этом случае вам также необходимо сначала сохранить фрагменты в автономном хранилище (например, с помощью FileSystem API) и сохранить их на диск пользователя только тогда, когда у вас есть файл целиком.
  • Размер фрагмента: это мельчайшие «атомы» данных вашего приложения. Разделение на фрагменты необходимо, поскольку в настоящее время существует ограничение на размер отправки (хотя это будет исправлено в будущей версии каналов данных). Текущая рекомендация по максимальному размеру фрагмента — 64 КБ.

Как только файл будет полностью передан другой стороне, его можно будет загрузить с помощью тега привязки:

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

Эти приложения для обмена файлами на PubShare и GitHub используют эту технику. Они оба имеют открытый исходный код и обеспечивают хорошую основу для приложения для обмена файлами на основе RTCDataChannel .

Так что ты можешь сделать?

RTCDataChannel открывает двери для новых способов создания приложений для обмена файлами, многопользовательских игр и доставки контента.

  • Одноранговый обмен файлами, как описано ранее.
  • Многопользовательские игры в сочетании с другими технологиями, такими как WebGL, как показано в BananaBread от Mozilla.
  • Доставка контента заново изобретена PeerCDN , инфраструктурой, которая доставляет веб-ресурсы посредством одноранговой передачи данных.

Измените способ создания приложений

Теперь вы можете предоставлять более привлекательные приложения, используя высокопроизводительные соединения с малой задержкой через RTCDataChannel . Платформы, такие как PeerJS и PubNub WebRTC SDK , упрощают реализацию RTCDataChannel , а API теперь имеет широкую поддержку на всех платформах.

Появление RTCDataChannel может изменить ваше представление о передаче данных в браузере.

Узнать больше