Веб-разработка

WebSocket и Real-time

Binance WebSocket API обрабатывает 100 миллионов WebSocket сообщений в сутки - котировки криптовалют в реальном времени для трейдеров по всему миру. Задержка: менее 10ms от биржи до клиента. При polling каждые 30 секунд 99.99% трейдеров потеряли бы деньги на устаревших ценах.

  • **Slack**: переход с polling на WebSocket в 2013 снизил latency сообщений с 30 сек до 200ms - разница между email и мессенджером
  • **ChatGPT/Claude API**: SSE для streaming токенов - каждое слово в ответе приходит отдельным событием
  • **Figma**: WebSocket для real-time collaborative editing - каждое движение курсора синхронизируется между участниками

WebSocket: постоянный двунаправленный канал

Slack в 2013: первый вариант использовал polling каждые 30 секунд. Задержка сообщений - до 30 секунд. После перехода на WebSocket - задержка менее 200ms. Это разница между приложением для переписки и мессенджером.

WebSocket - протокол RFC 6455 поверх TCP. Начинается с HTTP Upgrade handshake: клиент отправляет GET с заголовками `Upgrade: websocket` и `Sec-WebSocket-Key`, сервер отвечает 101 Switching Protocols. После этого HTTP соединение превращается в WebSocket - сырой TCP канал с фреймингом. Обе стороны могут отправлять данные в любой момент без запрос-ответ цикла.

WebSocket vs HTTP/2 Server Push: HTTP/2 добавляет multiplexing и server push в HTTP, но это однонаправленная инициатива от сервера. WebSocket - полнодуплексный канал: обе стороны равноправны. gRPC bidirectional streaming над HTTP/2 технически схож с WebSocket для server-client коммуникации. Выбор зависит от экосистемы: browser + arbitrary data = WebSocket, gRPC-web для TypeScript клиентов.

WebSocket соединение установлено. Клиент отправляет сообщение. Что происходит на транспортном уровне?

Socket.IO: WebSocket с батарейками

Чистый WebSocket - это raw протокол. Нет комнат, нет namespace, нет автоматического reconnect, нет fallback при блокировке WebSocket корпоративным proxy. Socket.IO решает все эти проблемы, добавляя слой абстракции над транспортом: приоритет WebSocket, fallback на HTTP long-polling.

Socket.IO features: автоматический reconnect с exponential backoff, namespace (изоляция потоков событий), rooms (broadcast к группе), acknowledgments (подтверждение доставки), multiplexing через один WebSocket. Но Socket.IO не совместим с чистым WebSocket клиентом - это собственный протокол поверх WebSocket.

Socket.IO горизонтальное масштабирование: если несколько Node.js процессов обслуживают WebSocket соединения, событие в room может затронуть клиентов на разных инстансах. Решение: Socket.IO Redis Adapter. Pub/Sub через Redis: когда сервер хочет broadcast в room, он публикует в Redis канал, все инстансы получают и рассылают своим клиентам. Sticky sessions - альтернатива: направлять одного клиента всегда на один инстанс.

Socket.IO приложение масштабируется на 3 сервера. Клиент A на сервере 1 хочет отправить сообщение в room 'trading'. Клиент B в той же room - на сервере 3. Без adapter - получит ли B сообщение?

Server-Sent Events: однонаправленный стриминг

Не каждое real-time приложение требует двунаправленности. Dashboard с метриками, лента новостей, прогресс загрузки, live sports scores - данные текут от сервера к клиенту. WebSocket для этого избыточен. SSE (Server-Sent Events) - стандарт W3C специально для этого сценария: HTTP/1.1 + chunked transfer encoding.

SSE проще WebSocket в нескольких аспектах: работает поверх обычного HTTP (прозрачен для proxy и CDN), автоматический reconnect встроен в браузер (EventSource), text-based (JSON нативно), поддерживает event types и Last-Event-ID для resumption. Ограничение: только сервер -> клиент, максимум 6 concurrent SSE соединений в HTTP/1.1 (нет ограничений в HTTP/2).

OpenAI ChatGPT API использует SSE для стриминга токенов - именно поэтому ответ появляется посимвольно, а не весь сразу. Каждый токен = одно SSE событие. GitHub Copilot, Anthropic Claude API - тот же паттерн. SSE идеален для streaming AI responses: HTTP/2 совместим, нет connection overhead как у WebSocket, текст отправляется сразу как генерируется.

Нужно обновлять real-time price ticker на странице (только сервер -> клиент, 1 раз в секунду). SSE или WebSocket?

Long Polling: когда WebSocket недоступен

Некоторые корпоративные proxy блокируют WebSocket (нестандартный upgrade). Некоторые мобильные сети имеют проблемы с долгими соединениями. Long polling - HTTP-based fallback: клиент делает HTTP запрос, сервер держит его открытым до появления данных (или timeout), клиент сразу делает следующий запрос. Имитация push через pull.

Сравнение техник: Regular polling (1 req/sec): высокий overhead, гарантированная задержка до T. Long polling: задержка минимальная при появлении данных, overhead на reconnect. SSE: один long-lived HTTP connection, идеален для streaming. WebSocket: двунаправленный, минимальный overhead per message. Выбор зависит от требований к latency, направленности данных и инфраструктурных ограничений.

WhatsApp Web в 2013 использовал long polling до перехода на WebSocket. Facebook Messenger использовал long polling до 2011. Сейчас long polling - в основном fallback стратегия в Socket.IO (при блокировке WebSocket корпоративным proxy). Если WebSocket недоступен, Socket.IO автоматически переключается на long polling - прозрачно для приложения.

WebSocket всегда лучше polling - нужно всегда использовать WebSocket для real-time

Выбор техники зависит от направленности данных, инфраструктуры и требований к latency: SSE для server->client, WebSocket для двунаправленного, polling для простых сценариев

WebSocket требует поддержки на всех уровнях (proxy, CDN, load balancer). SSE работает через любой HTTP инфраструктуру. Для AI streaming (ChatGPT) SSE оказался правильным выбором. Правильный инструмент зависит от задачи

Long polling сервер держит 1000 открытых HTTP соединений. Что является узким местом?

Связанные темы

Real-time коммуникация пересекается с протоколами, безопасностью и мобильной разработкой:

  • HTTP и сетевые протоколы — WebSocket начинается как HTTP upgrade - понимание HTTP/1.1 и TCP обязательно
  • Push Notifications — APNS/FCM - альтернатива WebSocket для mobile real-time когда app в background
  • DDoS и безопасность — WebSocket connection flood - вектор DoS; rate limiting на уровне WS connections

Ключевые идеи

  • **WebSocket**: HTTP upgrade -> TCP канал с фреймингом; полнодуплексный, минимальный overhead per message; wss:// для production
  • **Socket.IO**: абстракция над WebSocket с rooms, namespace, reconnect, fallback; Redis adapter для горизонтального масштабирования
  • **SSE**: однонаправленный server->client стриминг поверх HTTP; встроенный reconnect в браузере; идеален для AI streaming и dashboards
  • **Long polling**: HTTP fallback для ограниченных окружений; Socket.IO использует автоматически при блокировке WebSocket

Вопросы для размышления

  • Collaborative editor (как Figma или Google Docs) - какой транспорт выбрать? Что происходит при конфликте одновременных изменений?
  • WebSocket соединение упало. Как клиент должен обрабатывать reconnect? Что делать с сообщениями, отправленными пока соединение было разорвано?
  • ChatGPT использует SSE для streaming токенов. Почему не WebSocket, несмотря на его 'превосходство'?

Связанные уроки

  • web-05 — HTTP/1.1 и TCP - протокольная основа которую WebSocket расширяет через upgrade механизм
  • web-16 — Bundlers оптимизируют WebSocket клиент код для production
  • mob-15 — Push notifications - альтернативный канал для real-time когда WebSocket недоступен в mobile background
  • sec-15 — WebSocket connections могут быть вектором DoS - connection exhaustion атаки
  • par-09 — Event loop - основа обработки тысяч WebSocket соединений в Node.js без threading
  • net-21-http-basics
WebSocket и Real-time

0

1

Войти