Real-Time Backend
Data Channels
Figma позволяет 100 коллабораторам одновременно двигать курсоры и редактировать один файл без задержек. Cursor positions обновляются 60 раз/сек от каждого участника. Это 100 * 60 = 6000 сообщений/сек - через WebSocket это убьёт сервер. Как это работает?
- **Figma** использует RTCDataChannel для cursor positions (unordered, unreliable) и отдельный канал для объектов (ordered, reliable). P2P между пользователями в одной комнате снимает нагрузку с серверов и снижает latency с ~80ms до ~15ms для соседних регионов.
- **Discord** Go Live (screen share) и Video Calls используют DataChannels для передачи вспомогательных данных: speaking indicators, noise suppression controls, hardware stats. Медиа идёт через WebRTC media tracks, control data - через DataChannel.
- **agar.io** в ранние годы использовал DataChannels для P2P синхронизации состояния игры между 4-8 игроками в одной комнате - это позволяло запустить продукт без dedicated game servers. При масштабировании выше 8 игроков перешли на WebSocket сервер.
- **WebTorrent** (bittorrent в браузере) использует RTCDataChannel для peer-to-peer передачи чанков файлов между браузерами. 1M+ пользователей передают файлы без центрального сервера, только через torrent tracker для initial peer discovery.
RTCDataChannel
RTCDataChannel - механизм передачи произвольных данных между браузерами напрямую по P2P, поверх SCTP/DTLS. В отличие от WebSocket, данные идут без промежуточного сервера - latency определяется только сетью между пирами, а не RTT до сервера и обратно.
SCTP (Stream Control Transmission Protocol) под капотом data channels поддерживает мультиплексирование потоков, частичную надёжность и изменение порядка доставки. Это принципиально отличает его от TCP (всегда ordered+reliable) и UDP (всегда unordered+unreliable).
Чем RTCDataChannel принципиально отличается от WebSocket для передачи данных между двумя клиентами?
Ordered vs Unordered
Параметр `ordered` определяет, гарантируется ли порядок доставки сообщений. При `ordered: true` (default) SCTP буферизует пакеты и передаёт приложению строго по порядку - как TCP. При `ordered: false` сообщения передаются приложению немедленно по прибытии, возможно в произвольном порядке.
Unordered delivery снижает head-of-line blocking - ситуацию, когда потеря одного пакета задерживает все последующие. Для real-time данных (позиции игроков, cursor movement в Figma) свежее сообщение важнее потерянного старого.
Google Docs реализует collaborative editing через Operational Transformation. Какой режим ordering подходит для передачи операций редактирования?
Reliable vs Unreliable
Параметры `maxRetransmits` и `maxPacketLifetime` переводят канал в режим частичной надёжности (partial reliability). `maxRetransmits: 0` означает fire-and-forget - как UDP. `maxPacketLifetime: 100` означает ретрансмиссию только в течение 100ms, потом пакет отбрасывается.
Discord использует RTCDataChannel для передачи игрового overlay и статусов присутствия - unordered, maxRetransmits: 0. Figma использует ordered reliable channel для синхронизации векторных объектов и unordered unreliable для cursor positions (~60 updates/sec от каждого коллаборатора).
Приложение передаёт обновления позиции мыши ~60 раз/сек. Пакет с позицией должен доставляться в течение 33ms или не нужен совсем. Правильная конфигурация?
Data Channels в играх
Браузерные игры с P2P мультиплеером (и приложения типа Figma, Miro) используют несколько data channels одновременно - каждый с оптимальными параметрами для своего типа данных. Это имитирует разделение UDP/TCP в нативных играх.
Limit теоретического bandwidth RTCDataChannel - ~256KB/сообщение (Chrome). Netflix experiments с P2P CDN через DataChannels для peer-assisted delivery показали 40% снижение нагрузки на origin серверы при достаточной плотности пиров. agar.io (15M MAU) использовал DataChannels для multiplayer до перехода на dedicated servers при росте.
RTCDataChannel медленнее WebSocket, потому что P2P - нет гарантии пропускной способности
RTCDataChannel быстрее WebSocket для peer-to-peer данных, потому что исключает RTT до сервера. Задержка = RTT между пирами, а не 2*RTT через сервер.
WebSocket: клиент A -> сервер -> клиент B = 2 RTT. DataChannel: клиент A -> клиент B = 1 RTT. При 50ms между пирами и 100ms до сервера WebSocket добавляет 150ms latency против 50ms P2P. Это критично для игр, где порог восприятия задержки ~100ms.
В P2P браузерной игре 4 игрока (Mesh топология). Сколько RTCDataChannel соединений нужно для позиций, если каждый игрок должен получать данные от всех остальных?
Итоги
- **RTCDataChannel** работает поверх SCTP/DTLS, обеспечивает P2P передачу данных без сервера. Создаётся до SDP offer/answer.
- **ordered: false** устраняет head-of-line blocking - критично для real-time данных, где свежее сообщение важнее потерянного старого.
- **maxRetransmits / maxPacketLifetime** позволяют настроить partial reliability - компромисс между гарантией доставки и latency.
- **Multi-channel паттерн**: несколько каналов с разными параметрами для разных типов данных - как TCP+UDP разделение в нативных играх.
Связанные темы
DataChannels дополняют медиа-возможности WebRTC и используются в различных топологиях:
- STUN и TURN — DataChannel соединение тоже проходит через ICE с STUN/TURN - те же NAT traversal проблемы что и для медиа
- Media Streams — Media tracks и DataChannels мультиплексируются в одном RTCPeerConnection; DataChannel используется для control messages к медиа потокам
- MCU vs SFU vs Mesh — DataChannels в Mesh топологии требуют N*(N-1)/2 соединений - именно это делает Mesh неэффективным при большом числе участников
Вопросы для размышления
- Figma поддерживает collaborative editing через сервер, а cursor positions - через P2P DataChannel. Почему именно такое разделение?
- В игре с 8 игроками Mesh даёт 28 peer connections на каждого. При каком числе участников Mesh становится практически неприменим и почему?
- maxRetransmits: 0 и maxPacketLifetime: 0 - одно и то же? Что происходит с пакетом в каждом случае?