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