Перейти к содержанию
HexaTransfer
Вернуться к блогу
Технические погружения

WebSocket vs HTTP для Передача файлов: A Comparison

Compare WebSocket и HTTP protocols для файл transfer. Performance benchmarks, use cases, и implementation trade-offs explained.

Для передачи файлов HTTP выигрывает почти всегда. Протокол без состояния, работает через любой корпоративный прокси, получает выгоду от HTTP/2 мультиплексирования и HTTP/3 QUIC, и интегрируется с CDN, presigned URL и API объектных хранилищ вроде S3. WebSocket (RFC 6455) блистает для двунаправленных сообщений в реальном времени, чатов, совместного редактирования, живых дашбордов — но даёт мало преимуществ для перемещения больших файлов и вносит реальные недостатки: нет нативного кэширования, плохая поддержка CDN, проблемы с промежуточными узлами, более сложное управление памятью на сервере. Детальное сравнение с цифрами.

Принципиальное различие протоколов

HTTP — это запрос-ответ, без состояния, с возможностью кэширования. Каждый запрос несёт заголовки, попадает на сервер или CDN, возвращает ответ. HTTP/2 мультиплексирует много запросов на одном TCP-соединении; HTTP/3 (RFC 9114) работает поверх QUIC с улучшенным восстановлением при потерях и нулевым RTT при возобновлении. WebSocket начинается как HTTP Upgrade-запрос, затем переводит TCP-соединение в полнодуплексный протокол на основе фреймов. После апгрейда обе стороны могут отправлять сообщения в любое время. Этот постоянный двунаправленный канал мощен для интерактивных приложений, но архитектурно неуклюж для массовой передачи файлов, где поток подавляюще однонаправленный.

Бенчмарки пропускной способности и задержки

На гигабитном канале между клиентом в Москве и сервером в US-East типичные бенчмарки показывают: HTTP/1.1 одиночный PUT — примерно 40–80 Мбит/с из-за ограничений масштабирования TCP-окна, HTTP/2 multipart (8 параллельных потоков, чанки по 8 МБ) — 400–800 Мбит/с, HTTP/3 поверх QUIC — немного лучше при потерях пакетов на 10–30%, WebSocket с бинарными фреймами — 200–500 Мбит/с, ограниченный управлением потоком одного соединения. Паттерн повторяется на разных расстояниях. WebSocket не быстрее, потому что под капотом всё равно TCP, но использует соединение менее эффективно, чем параллельные HTTP-запросы.

Чанкование и возобновляемые загрузки

У HTTP хорошо определённые стандарты чанковой загрузки. Протокол tus.io использует HTTP PATCH с заголовками Upload-Offset. S3 Multipart Upload использует UploadPart с номерами частей и ETag. Оба переживают прерывания сети, перезапускаются с последнего успешного чанка и работают после перезапуска клиента благодаря состоянию в IndexedDB. Чанкование WebSocket — ad-hoc: вы определяете собственное фреймирование, порядковые номера и подтверждения. Каждая команда изобретает велосипед возобновления, обычно хуже, чем проверенные HTTP-варианты. SocketIO, Primus и кастомные протоколы переизобретают одно и то же с тонкими багами.

Совместимость с CDN и edge

CDN вроде Cloudflare, CloudFront, Fastly и Akamai кэшируют HTTP-ответы на edge-узлах, часто вдвое снижая время скачивания глобально. GET-запросы для статичных объектов можно кэшировать по URL или подписанному URL. Трафик WebSocket обычно проходит через CDN, но не кэшируется, и многие корпоративные прокси отключают или ограничивают апгрейд WebSocket. Корпоративные сети с перехватывающими TLS-прокси иногда полностью ломают WebSocket. Для сервиса передачи файлов с глобальной аудиторией этого уже достаточно для предпочтения HTTP: 300+ точек присутствия Cloudflare делают ближайшие скачивания значительно быстрее для HTTP, но мало что дают для WebSocket.

Использование серверных ресурсов

HTTP-серверы обрабатывают тысячи параллельных соединений при минимальной памяти, потому что запросы кратковременны. Nginx, Caddy и Go net/http поддерживают 10 000+ параллельных соединений на узел при скромной RAM. Каждое WebSocket-соединение долгоживущее — держит TCP-сокет, буфер чтения, буфер записи и часто состояние приложения. При масштабировании WebSocket-флоты требуют тщательной настройки ulimit, TCP keepalive и памяти на соединение. Развёртывания Kubernetes сталкиваются с проблемами sticky sessions WebSocket и корректного завершения при rolling deploy. Для сервиса передачи, обрабатывающего пиковые короткие загрузки, модель HTTP менее болезненна.

Presigned URL и прямые загрузки в хранилище

Убийственная функция HTTP для передачи файлов — presigned URL. Ваше приложение генерирует подписанный URL, указывающий прямо на S3, R2 или GCS, и клиент загружает прямо в объектное хранилище. Серверы приложений никогда не касаются байт. Нет прокси-полосы, нет давления на память, нет файлового ввода-вывода. Для WebSocket эквивалента не существует. Чтобы использовать WebSocket для загрузок, нужно проксировать через сервер приложений, который затем пишет в хранилище — что удваивает стоимость полосы и добавляет задержку. Загрузка 10 ГБ по конвейеру WebSocket-сервер-S3 использует 20 ГБ серверной полосы; прямые HTTP-загрузки в S3 используют полосу серверов только для небольших вызовов метаданных.

Когда WebSocket реально помогает

WebSocket хорошо вписывается в файло-смежные рабочие процессы. Уведомления о прогрессе загрузки в реальном времени между вкладками или устройствами: WebSocket-трансляции доставляются мгновенно. Совместное редактирование файлов: yjs, Automerge и похожие CRDT-библиотеки используют WebSocket для небольших дельта-сообщений, а реальные большие ресурсы передаются через HTTP. Живая сигнализация для WebRTC peer-to-peer передач: WebSocket — стандартный транспорт сигнализации до открытия P2P каналов данных. Серверные push-уведомления о скачивании файла получателем: WebSocket позволяет мгновенно уведомить отправителя без опроса. Паттерн — WebSocket для событий, HTTP для байт.

Преимущества HTTP/2 и HTTP/3

HTTP/2 (RFC 7540) и HTTP/3 (RFC 9114) закрывают большинство пробелов, которые раньше эксплуатировал WebSocket. HTTP/2 мультиплексирует несколько запросов на одном TCP-соединении, устраняя лимит в 6 соединений на origin. Server Push позволяет серверам отправлять ресурсы упреждающе, сокращая round trip. HTTP/3 работает поверх QUIC, который обрабатывает потерю пакетов по потокам, не блокируя всё соединение — критично на нестабильных мобильных сетях. Server-Sent Events (EventSource) обеспечивают однонаправленный серверный push поверх HTTP — проще WebSocket, когда push нужен только от сервера.

Безопасность и контроль origin

История безопасности HTTP зрелая. CORS контролирует, какие origin могут загружать или скачивать. CSP ограничивает источники клиентских запросов. TLS 1.3 обеспечивает транспортную безопасность. Presigned URL включают HMAC-подписи для предотвращения подделки и могут быть ограничены конкретными ключами объектов с временем истечения. WebSocket имеет более слабый контроль origin. Заголовок Origin может быть подделан не-браузерными клиентами. Многие WebSocket-серверы не валидируют origin, что приводит к атакам межсайтового перехвата WebSocket. Реализация эквивалентной защиты требует тщательной валидации токенов для каждого фрейма.

Когда что выигрывает

| Критерий | HTTP | WebSocket | |---|---|---| | Загрузка/скачивание больших файлов | Выигрывает (multipart, presigned URL, CDN) | Проигрывает (один поток, нет кэширования) | | Двунаправленные сообщения реального времени | Проигрывает (опрос расточителен) | Выигрывает (нативный full-duplex) | | Совместимость с CDN | Выигрывает (глобальный edge-кэш) | Проигрывает (редко кэшируется) | | Серверные ресурсы при масштабировании | Выигрывает (без состояния, краткие соединения) | Проигрывает (долгоживущие, RAM на соединение) | | Совместимость с корпоративными прокси | Выигрывает (стандартный HTTP) | Проигрывает (прокси часто блокируют Upgrade) | | Возобновляемые загрузки | Выигрывает (tus.io, S3 multipart) | Ad-hoc (требует самодельной реализации) |

Для сервиса передачи файлов вроде HexaTransfer, HTTP плюс чанковый multipart плюс прямые загрузки в S3 — правильная архитектура, с опциональным WebSocket для живого прогресса или событий уведомления получателя поверх.

Попробуйте на hexatransfer.com — бесплатно, без регистрации, до 10 ГБ.

Безопасная отправка больших файлов со сквозным шифрованием

Передавайте файлы до 10 ГБ бесплатно со сквозным шифрованием. Регистрация не требуется. Ваши файлы шифруются в браузере перед загрузкой — никто другой не может их прочитать.

Отправить файл