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

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

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

Зачем нужен еще один канал передачи данных?

У нас есть WebSocket , AJAX и Server Sent Events . Зачем нам ещё один канал связи? 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 разработан для точной имитации RTCDataChannel и поддерживает строки , а также некоторые двоичные типы данных JavaScript, такие как Blob , ArrayBuffer и ArrayBufferView . Эти типы могут быть полезны при передаче файлов и многопользовательских играх.

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

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

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

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

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

Далее вы узнаете, как настроить 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: Stream Control Transmission Protocol и Stream Control Transmission Protocol Partial Reliability Extension .

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

Большинству пользователей достаточно использовать только первые три параметра: ordered , maxPacketLifeTime и maxRetransmits . В протоколе SCTP (теперь используемом всеми браузерами с поддержкой WebRTC) значения reliability и ordered по умолчанию равны true. Если вам нужен полный контроль на уровне приложения, имеет смысл использовать unreliable и unordered , но в большинстве случаев частичная надежность полезна.

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

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

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

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

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

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

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

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

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

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

  • Размер файла: если размер файла достаточно мал и может быть сохранён и загружен как один BLOB-объект, вы можете загрузить его в память с помощью 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 может изменить ваше представление о передаче данных в браузере.

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