Всем привет. Подскажите, какой-то хороший и быстрый способ, чтобы отображать на сайте или в приложении, что пользователь онлайн?
У меня приложение android и iphone. Я на каждый запрос пользователя, делал запрос в БД, где сохранял время последнего визита. Но потом понял, что обновлять записи в таблицах, это времязатратно. Обновление происходит за 15мс, что в масштабах всего запроса, сильно долго, ведь все get запросы выполняются гораздо быстрее в итоге весь скрипт отрабатывает за 7мс, а запрос на обновление визита, аж 15-20мс. Итого 22-27мс, вместо 7. И так на каждый запрос.
Была идея хранить где-то в redis, но тогда, после получении пользователя из бд, нужно еще лезть в redis, в общем вариантов больше нет
edward_freedom, это и есть мой первый вариант - я так и едлаю. Любое действие (открытие ленты, страницы, лайк или еще что-то. в общем любой запрос к серверу) - запрос в базу на обновление онлайн.
DanKud, Сложность вытаскивания. Получается при любом запросе, мне по несколько раз придется перебирать полученные записи юзеров и добавлять к ним время из внешнего источника (Redis). Не знаю, возможно так и делают, поэтому и задаю этот вопрос. Мне просто этот вариант показался чересчур массивным
Алексей, не совсем понимаю о каких "мне по несколько раз придется перебирать полученные записи юзеров" идет речь. Redis это такая же база данных, только хранящая данные в оперативной памяти. Никаких переборов делать не надо, все данные хранятся как "ключ-значение".
edward_freedom, правильно, а теперь предствиим, приложение получает список пользователей, ему так же нужно отобралить кто сейчас онлайн. Я вытаскиваю сначала юзеров из бд, потом беру id полученных юзеров и тащу их в редис, чтобы для каждого получить значение последнего визита. Затем мне нужно раскидать полученные данные в каждого юзера. Вот весь этот процесс и создаст постоянные переборы массивов с данными. С бд все было проще, я просто беру поле last_visit и отдаю его вместе со всеми остальными
Алексей, вопрос был, как текущему пользователю менять статус онлайна, не о каком списке и массиве речь не шла. Может ты не правильно мою идею понял. Суть в том, что ты когда делаешь выборку, сразу добавляешь запрос на обновление.
edward_freedom, а если я задам вопрос "как авторизовать пользователя" это не будет подразумевать вопрос о том, что открывая любую страницу, этот пользователь не должен вводить пароль заново?
Судя по всему проблема кроется не в записи в базу данных, а в том, когда и как часто вы это делаете.
Неправильный подход - клиентское приложение периодически по таймеру делает запрос к серверу, время последнего запроса пишется в базу.
Правильный подход - клиентское приложение открывает и держит открытым сетевое соединение (websocket например, все браузеры поддерживают, ну а приложения могут сами ниже уровнем tcp использовать), в этом случае приложению так или иначе придется отсылать в это подключение ping пакет (keep alive таймаут) но в этом случае закрытие приложение пользователем будет отловлено в тот же миг по закрытию сетевого подключения, т.е. в базу данных на сервере не нужно ничего писать, бакэнд сможет по списку открытых подключений все сказать сам.
Да, если у пользователя смартфон - то в момент ухода в сон или из-за проблем с сетью (смена базовой станции при движении или просто рукожопство ОпСоС-ов) соединение тоже может закрыться или наоборот подвиснуть и в пределах таймаута выдавать неверную информацию (т.е. человек приложение закрыл а сервер это не отловил) но окно ошибки в этом случае будет тот же таймаут, что был бы в первом неправильном способе.
Подробно не изучал но в качестве намеков и голословных утверждений, на просторах инетернета говорят, что без серьезной нагрузки на батарею уведомления хорошо отрабатываются в режиме сна, через google cloud api https://habr.com/ru/post/345942/
Разум мне подсказывает что необходимо просто правильно настроить свою службу (только они могут работать в режиме сна)
p.s. батарею кушает не служба и открытые подключения а работающий wifi (а так же gsm/edge и кажется 3g, потому что в россии для голоса и интернета используются разные каналы), в случае же с мобильными сетями типа lte и выше, дополнительных затрат не предвидится
Но так как при наличии gaps и хотя бы одного чата канал и так будет держаться открытым, еще один сервис погоды не сделает