Передача данных между двумя браузерами для общения, игр или передачи файлов может быть довольно сложным процессом. Для этого требуется настройка и оплата сервера для ретрансляции данных, а также, возможно, масштабирование до нескольких центров обработки данных. В этом случае возможны высокие задержки и сложно обеспечить конфиденциальность данных.
Эти проблемы можно решить, используя 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 перспективным вариантом для веб-приложений.
Для успешного перевода необходимо выполнить несколько шагов:
- Чтение файла в JavaScript с использованием File API .
- Создайте одноранговое соединение между клиентами с помощью
RTCPeerConnection
. - Создайте канал данных между клиентами с помощью
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
может изменить ваше представление о передаче данных в браузере.