WebSocket: просто о сложном. Часть 2 — практическое применение и тонкости

от автора

С вами снова Юля, системный аналитик из EvApps и мы продолжаем разбираться в технологии WebSocket. В первой части (WebSocket для начинающих системных аналитиков: просто о сложном. Часть 1), мы познакомились с основами WebSocket, а теперь давайте заглянем под капот реального сайта, например, криптобиржи. Попробуем понять, как работает этот сложный механизм: что происходит, когда вы видите мгновенно меняющиеся котировки и графики, и что происходит “за кулисами”.

Эта статья для вас, если вы:

  • Начинающий системный аналитик и хотите понять, как устроены сложные веб-приложения.

  • Интересуетесь, как работает frontend и backend 

  • Просто любопытны и хотите узнать, как работает технология WebSocket

Какие вопросы рассмотрим?

  • Как происходит обмен данными через WebSocket между браузером и сервером криптобиржи?

  • Как убедиться, что соединение безопасно и ваши данные не попадут в чужие руки?

  • Как WebSocket влияет на производительность сервера?

  • Не упадет ли сайт, если слишком много пользователей одновременно захотят торговать?

Готовы погрузиться в мир технологии WebSocket? Поехали!

WebSocket в реальном времени: пример криптобиржи

Рассмотрим сайт для торговли криптовалютой, где важна скорость и точность передачи данных. Например, когда вы видите обновление курса биткоина в реальном времени или получаете уведомление о сделке, всё это работает благодаря WebSocket.

Frontend и Backend: как они взаимодействуют?

Frontend — это то, что видит пользователь: интерфейс сайта, графики, кнопки. Когда вы заходите на сайт, frontend отправляет запрос на установление WebSocket-соединения с backend.

Backend — это “мозг” системы. Он обрабатывает запросы, работает с базой данных и отправляет данные обратно на frontend. В случае с сайтом backend отвечает за передачу данных о курсах валют, балансе пользователя и т.д.

Как это выглядит на практике?

  1. Пользователь открывает сайт платформы

  2. Frontend устанавливает WebSocket-соединение с backend

  3. Backend начинает отправлять данные в реальном времени: обновления курсов, уведомления о сделках и т.д.

  4. Frontend отображает эти данные на экране пользователя

Как убедиться, что используются  WebSocket?

  • В браузере можно использовать инструменты разработчика (DevTools), чтобы увидеть WebSocket-соединения.

Посмотрим на примере одного из таких сайтов

  • Перейдите на страницу https://www.bybit.com/en

  • Откройте Инструменты разработчика (F12)

  • Перейдите на вкладку Network (Сеть)

  • Выберите фильтр WS (Websocket)

  • Выберите конкретное соединение, чтобы увидеть заголовки (Headers)

Если WebSocket используются, то вы увидите активные соединения с типом WebSocket, заголовки запросов, фреймы данных, которые отправляются и принимаются.

Как backend работает с WebSocket? Или что происходит под капотом?

Давайте рассмотрим  подробнее.

1. Установление соединения

(*Из первой части мы помним, что  соединение WebSocket начинается с обычного HTTP-запроса.)

Когда пользователь открывает сайт, frontend отправляет HTTP-запрос с заголовком “Upgrade: websocket”.
Backend проверяет этот запрос и, если всё в порядке, отвечает статусом “101 Switching Protocols”. Соединение переходит на протокол WebSocket, и HTTP больше не используется.

 *Может ли WebSocket работать без HTTP?

— Нет, без начального HTTP-запроса WebSocket не могут быть установлены. Это обязательный этап для начала работы WebSocket.

Что делает backend на этом этапе?

  • Проверяет заголовки запроса (например,“Sec-WebSocket-Key”).

  • Генерирует ответный ключ (“Sec-WebSocket-Accept”).

  • Устанавливает соединение и выделяет ресурсы для его поддержания.

Вкладка  Headers (Заголовки)
Здесь находится общая информация и заголовки запроса и ответа
Итак,
General (Общая информация) содержит:

Request URL: URL WebSocket-сервера, к которому подключается клиент. wss:// указывает на зашифрованное соединение (далее поговорим про безопасное соединение немного подробнее)

Request Method: метод HTTP-запроса, который используется для handshake

Status Code: 101 Switching Protocols — подтверждает, что протокол был успешно изменен с HTTP на WebSocket.

Request Headers (Заголовки запроса):

Это заголовки, которые клиент отправляет серверу.

  • Connection: Upgrade — указывает, что клиент хочет обновить соединение до другого протокола.

  • Upgrade: websocket — указывает, что клиент хочет обновить соединение до WebSocket.

  • Sec-WebSocket-Key — случайный ключ, используемый для handshake.

  • Sec-WebSocket-Version — версия протокола WebSocket (обычно 13).

Response Headers (Заголовки ответа):

Это заголовки, которые сервер отправляет клиенту в ответ.

  • Connection: upgrade — подтверждает, что сервер согласен обновить соединение.

  • Upgrade: websocket — подтверждает, что сервер обновил протокол до WebSocket.

  • Date — дата и время отправки ответа сервером.

  • Sec-WebSocket-Accept — ключ, сгенерированный сервером для проверки подлинности ответа рукопожатия.

(* Рассматриваем стандартные заголовки)

Набор заголовков при установке соединения по протоколу WebSocket  может отличаться в зависимости от реализации, требований клиента и сервера.

2. Обмен данными

После установления соединения начинается двусторонний обмен данными между клиентом и сервером.

Вкладка Messages (Сообщения)
В этой вкладке можем посмотреть данные, передаваемые через WebSocket:

  • Входящие (Incoming) ⬇️ и исходящие (Outgoing) ⬆️ сообщения.

  • Время отправки и получения каждого сообщения

  • Содержимое сообщений (текст или бинарные данные)

Как backend обрабатывает сообщения?

Backend получает сообщения от клиента (например, запросы на данные), обрабатывает их, обращается к базе данных, и отправляет обратно клиенту.

3. Поддержание соединения (Ping/Pong)

Для того чтобы клиент (frontend) и сервер (backend) понимали, что между ними есть активное соединение, они регулярно обмениваются Ping и Pong сообщениями.

Клиент отправляет сообщение:
“ping”

Сервер отвечает:
{
  “pong”: 1742678942258
}.

4. Закрытие соединения

Если сервер не получает Pong от клиента в течение определенного времени, он считает соединение разорванным и закрывает его. Это позволяет освободить ресурсы и избежать зависших соединений.

Как это выглядит в коде?

На примере криптобиржи фрейм ping/pong настроен так, что клиент отправляет “ping”, а сервер в ответ присылает “pong”.
Не нужно пугаться, если вы встретите другую реализацию, где сервер отправляет “ping”, такое тоже возможно и это не противоречит рекомендациям стандарта.

“ •  RFC 6455 рекомендует, но не требует, чтобы ping инициировался одной стороной, а pong отправлялся в ответ другой стороной.

   •  RFC говорит, что любая сторона может отправлять ping кадр в любое время.

  •  Получатель ping кадра обязан в ответ отправить pong кадр с тем же самым «payload» (данными), который был в ping. Это важно для корректной работы.”

Например, у нас на проекте (мы работаем над платформой для колл-центра) фрейм ping/pong реализован таким образом:
ping отправляется с сервера, а pong с клиента.
Для чего это сделали?
Для нас важны стабильность и доступность приложения.
Наш сервер поддерживает много клиентских соединений.

Если сервер считает, что клиент отвалился (то есть на свой ping не получит от клиента pong), это будет означать , что оператор не может принимать звонки и чаты, а это влияет на обслуживание клиентов. Сервер должен быстро обнаруживать проблемы с клиентскими соединениями. Именно по этой причине была выбрана такая реализация.
Учитывайте эти моменты при разработке систем с использованием WebSocket.

Безопасность: Не забываем про WSS

WebSocket-соединение должно быть защищено, особенно если речь идет о финансовых данных. Системный аналитик, не может не думать о безопасности. И вот как это обеспечивается:

  • WSS (WebSocket Secure) — это версия протокола Websocket с  шифрованием данных, аналогичная HTTPS.  Все данные передаются через защищенное соединение wss://, которое использует TLS/SSL для шифрования. Это предотвращает перехват данных злоумышленниками.

  • Аутентификация и авторизация: перед установлением WebSocket-соединения пользователь должен авторизоваться. Например, на сайте, который мы рассматриваем, это делается через API-ключи или токены.
    Backend проверяет эти данные и решает, можно ли установить соединение.

  • Ограничение запросов: backend проверяет, не слишком ли много запросов приходит от одного клиента, чтобы предотвратить атаки, такие как DDoS. Например, если клиент отправляет слишком много сообщений за короткий промежуток времени, сервер может временно заблокировать его.

Как убедиться, что используется WSS?

Откройте инструменты разработчика (DevTools) в браузере, чтобы проверить соединения в Websocket. Информацию о нем мы можно увидеть во вкладке Network

  • ws://… — обычный, небезопасный WebSocket.

  • wss://… — безопасный (зашифрованный) WebSocket (WebSocket Secure).    

Помним про безопасность)

Как WebSocket влияет на производительность?

WebSocket позволяет передавать данные быстро, но это создает нагрузку на сервер. Например, если тысячи пользователей одновременно подключены к сайту, сервер должен обрабатывать огромное количество сообщений. Как с этим справляются?

  • Балансировщики нагрузки (например, Nginx или AWS Elastic Load Balancer), которые распределяют запросы между несколькими серверами.

  • Кластеризация: несколько серверов работают вместе, обрабатывая запросы параллельно.

  • Очереди сообщений (например, RabbitMQ или Kafka), которые помогают управлять потоками данных.

Преимущества и недостатки WebSocket

Преимущества:

  • Снижение задержек. WebSocket устанавливают постоянное двустороннее соединение. Это позволяет мгновенно обмениваться данными без необходимости отправлять повторные запросы.

  • Уменьшение накладных расходов. В HTTP каждый запрос содержит заголовки, а это увеличивает объём передаваемых данных. WebSocket передают данные в “легком” формате, после установки соединения, экономя трафик.

  • Эффективное использование ресурсов.
    Сервер не тратит ресурсы на обработку тысяч повторных HTTP-запросов.
    Клиент не создает нагрузку на процессор из-за постоянного опроса сервера.

  • Масштабируемость. WebSocket упрощают реализацию функций реального времени. Подходят для высоконагруженных систем (соцсети), где важна скорость обработки данных.

  • Упрощение архитектуры. Нет необходимости использовать обходные решения (например, AJAX-запросы). Код становится чище, а поддержка проще.

Недостатки:

  • Ресурсная нагрузка соединения.
    Каждое WebSocket-соединение требует постоянного открытого канала между клиентом и сервером. Для сравнения: HTTP-запросы обрабатываются и закрываются, освобождая ресурсы.

  • Сложность масштабирования.
    WebSocket сложнее масштабировать горизонтально, так как состояние соединения “привязано” к конкретному серверу.

  • Избыточность для простых задач.
    Если приложению не нужны мгновенные обновления, WebSocket становится “стрельбой из пушки по воробьям”
    Например, для статического сайта-портфолио или блога с комментариями достаточно HTTP + AJAX.

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

Заключение

Итак, мы с вами заглянули и “под капот” сайта криптобиржи и разобрали, как frontend и backend взаимодействуют через WebSocket. Рассмотрели вопросы безопасности и масштабируемости.
Надеюсь, этот разбор помог вам лучше понять, как всё устроено! Если остались вопросы, задавайте — с удовольствием на них отвечу! 😊

А в следующей части мы поговорим от том, как тестировать WebSocket-соединения. Рассмотрим различные подходы и инструменты, которые помогут убедиться в корректной работе WebSocket приложений.


ссылка на оригинал статьи https://habr.com/ru/articles/896836/