Вместо того чтобы клиент постоянно спрашивал сервер (Polling), сервер сам отправляет данные клиенту в момент наступления события. Это подход Event-Driven.
1. WebHooks: Сервер становится клиентом
WebHook — это обратный вызов. Ты (как клиент) заранее даешь серверу свой URL и говоришь: «Когда пользователь оплатит заказ, сделай POST-запрос с данными вот по этому адресу». Так работает интеграция со Stripe, Telegram-ботами и GitHub Actions.
- Плюсы: Ноль холостых запросов. Мгновенное уведомление.
- Сложности: Тебе нужен публичный IP (или API Gateway), чтобы принять этот запрос. Обязательна безопасность, чтобы хакер не прислал тебе фейковый вебхук «Оплата прошла успешно». И нужны механизмы повтора запросов (что если твой сервер лежал, когда Stripe прислал вебхук?).
2. WebSockets: Двусторонняя магистраль
WebSocket (WS) — это протокол, обеспечивающий постоянное, Full-Duplex (двунаправленное) TCP-соединение. Клиент и сервер могут слать друг другу сообщения в любой момент.
Идеально для: чатов, онлайн-игр, биржевых тикеров и совместного редактирования документов.
Архитектурная боль: Как масштабировать WebSockets?
Проблема: WebSockets — это долгоживущие соединения. Если Алиса подключена к Серверу 1, а Боб к Серверу 2, то как Алисе написать Бобу?
- Решение 1: Stateless WebSockets + Pub/Sub: Инстансы приложения не хранят уникальное состояние. Алиса пишет Бобу -> Сервер 1 публикует событие в брокер (Valkey Pub/Sub) -> Сервер 2 вычитывает его и отправляет Бобу. Если Алиса зайдет в туннель и переподключится, балансировщик может кинуть её на Сервер 3. Сервер 3 просто заново подпишет её на Valkey. Это идеальный подход для масштабирования.
- Решение 2: Sticky Sessions (Для тяжелого State'а или оптимизации): Если переподключение и поднятие контекста пользователя (токены, права, подписки) стоит слишком дорого (по CPU) или сервер держит в RAM тяжелый стейт (как холст в Figma или матч в онлайн-игре), используют Sticky Sessions. Nginx запоминает клиента по куке и при кратковременном обрыве сети старается вернуть его на тот же самый сервер, чтобы не собирать контекст пользователя с нуля.
# Пример конфигурации Nginx для Sticky Sessions
upstream websocket_backend {
server ws1.example.com;
server ws2.example.com;
# Привязываем клиента к серверу через cookie на 1 час
sticky cookie srv_id expires=1h domain=.example.com path=/;
}