Online/offline статус пользователей в режиме реального времени

У нас в компании есть внутренний проект, на котором мы обучаемся в свободное время от основных проектов. Проект — мессенджер с функцией видеосвязи. Видеосвязь и месседжинг (возможность создавать и общаться в общих каналах) мы берём из стороннего SDK.

Клиентское приложение написано нативно под iOS и Android. Бэкенд на джаве.

В приложении есть стандартный список контактов. И сейчас появилась задача, отслеживать в режиме реального времени статус пользователя (в идеале, имплементировать функционал как в телеграме, типа "был в сети 5 часов назад") в списке контактов, и по заходу на его профиль.

Подскажите пожалуйста, в какую сторону смотреть? Что нужно сделать на сервере, и что на клиенте?

После часов гугления, я узнал, что существует такая технология как websocket, и такой инструмент как kafka. Можно ли это как-то связать?


Ответы (2 шт):

Автор решения: ЮрийСПб

Можно сделать сильно по разному, в зависимости от желаемого набора фич.

Но, в основе своей вам надо реализовать следующее:

  1. Способ определения когда юзер активен.
  2. Способ получения статуса активен/неактивен

Простейший способ, без сокетов будет такой:

  1. Когда юзер совершает какое-то действие, требующее соединения с сервером, на сервере, при поступлении запроса от юзера записывается время прихода запроса.
  2. Теперь, запрашивая с сервера инфу о к-л юзере вы можете отдавать и записанное в п1 время.

Такое реализовать максимально просто. Однако так вы не будете иметь статуса "активен прямо сейчас", если не определять "сейчас" как прошло не более n времени с последнего обращения юзера к серверу. Т.е. если юзер просто запустил приложение и смотрит часами на список чатов, не делая сетевых запросов он может быть воспринят как "неактивный"


Более сложный способ - постоянно уведомлять сервер о статусе юзера. Например - каждые n времени отправлять на сервер запрос пока приложение запущено. Это можно и обычными запросами делать или да, сокет соединение поддерживая, что может быть в ряде случаев предпочтительнее в смысле кол-ва запросов на сервер.

→ Ссылка
Автор решения: Ihor Soroka

В общем получилось решить следующим образом:

  1. В базе данных создаётся таблица user_activity (user_id, status, last_seen);
  2. Для этой таблицы создаётся функция-триггер, которая рассылает уведомления об изменениях в этой таблице;
  3. В коде создаётся слушатель этих самых уведомлений (событий);
  4. Каждый клиент во время подключения к веб-сокету передаёт свой id/username на веб-сокет контролер;
  5. Каждый раз, когда приходит обновление из соответствующей таблицы (users_activity), мы делаем:
  • достаём у каждого подключённого клиента список его контактов;
  • смотрим у кого в контактах есть пользователь, по которому пришло обновление с базы данных, и отправляем клиенту по веб-сокету соответствующий JSON, например
{    
    "username" : "username",    
    "status" : "online",   
    "last_seen" : 1152359098263742 
}

Как вам такое решение?

P.S. Объясните пожалуйста, почему у меня в ТС-посте показывает 51 рейтинг, а в профиле 1? Я невероятно туплю...

→ Ссылка