Ответ
Реализация индикатора онлайн-статуса в распределенной системе — это задача управления состоянием (presence management). Простого HTTP-запроса недостаточно, так как он не поддерживает постоянное соединение.
Правильная архитектура выглядит так:
1. Основная технология: WebSockets
Пользователь считается онлайн, пока у него активно WebSocket-соединение с сервером. Это обеспечивает постоянный канал связи.
2. Архитектура отслеживания
Подключение (Connect):
- Когда пользователь устанавливает WebSocket-соединение, сервер (Connection Gateway) аутентифицирует его и получает
userID
. - Сервер записывает информацию о том, что пользователь онлайн, в быстрое хранилище. Идеально для этого подходит Redis.
- Команда в Redis:
SADD online_users <userID>
(добавляем ID пользователя в множество).
- Когда пользователь устанавливает WebSocket-соединение, сервер (Connection Gateway) аутентифицирует его и получает
Отключение (Disconnect):
- Graceful: Если пользователь сам закрывает соединение, сервер получает событие
onClose
и удаляет его из Redis:SREM online_users <userID>
. - Ungraceful (обрыв связи): Соединение может оборваться без уведомления (пропал интернет, закрылся ноутбук). Для этого нужен механизм Heartbeat (пульс).
- Graceful: Если пользователь сам закрывает соединение, сервер получает событие
Механизм Heartbeat:
- Сервер периодически (например, каждые 30 секунд) отправляет клиенту
ping
сообщение по WebSocket. - Клиент, получив
ping
, должен немедленно ответитьpong
. - Если сервер не получает
pong
в течение заданного таймаута (например, 45 секунд), он принудительно закрывает соединение и считает пользователя оффлайн, удаляя его из Redis.
- Сервер периодически (например, каждые 30 секунд) отправляет клиенту
Проверка статуса:
- Чтобы узнать, онлайн ли конкретный пользователь, любой другой сервис может сделать быстрый запрос в Redis:
SISMEMBER online_users <userID>
. - Эта операция имеет сложность O(1), что делает её чрезвычайно эффективной.
- Чтобы узнать, онлайн ли конкретный пользователь, любой другой сервис может сделать быстрый запрос в Redis:
3. Оповещение об изменении статуса
Когда статус пользователя меняется (онлайн/оффлайн), сервер может опубликовать это событие в брокер сообщений (NATS, RabbitMQ). Другие пользователи, которые являются его друзьями или находятся с ним в одном чате, могут быть подписаны на эти события и мгновенно получать обновления в своем интерфейсе.