Метод setLastActivity: как корректно обновлять дату и время последней активности пользователя при переходе между страницами?
Метод `setLastActivity` используется для фиксации момента последней активности пользователя в системе. Это важно для функций «онлайн-статус», автоматического выхода по таймауту и аналитики поведения. Рассмотрим, как корректно реализовать обновление этой метки при переходе между страницами.
## Основные подходы к реализации
### 1. Серверная сторона (middleware)
Самый надёжный способ — обновлять `last_activity` в middleware при каждом HTTP-запросе:
php
// Laravel пример
public function handle($request, Closure $next)
{
if (Auth::check()) {
Auth::user()->setLastActivity();
}
return $next($request);
}
Метод модели:
php
public function setLastActivity()
{
$this->timestamps = false; // не трогаем updated_at
$this->last_activity_at = now();
$this->save();
}
### 2. Клиентская сторона (JavaScript)
При SPA (Single Page Application) переходы не вызывают полный HTTP-запрос, поэтому нужно отслеживать навигацию через роутер:
javascript
// Vue Router
router.afterEach(() => {
api.post(‘/user/activity’);
});
// React Router
useEffect(() => {
return history.listen(() => {
updateLastActivity();
});
}, [history]);
### 3. Дебаунсинг и троттлинг
Чтобы не перегружать базу данных при частых переходах, используйте дебаунс:
javascript
const updateActivity = debounce(() => {
api.post(‘/user/activity’);
}, 5000); // не чаще раза в 5 секунд
## Хранение данных
**В базе данных** — добавьте столбец `last_activity_at` типа `TIMESTAMP` в таблицу пользователей. Индексируйте его, если часто делаете выборки по онлайн-статусу.
**В кэше (Redis/Memcached)** — для высоконагруженных систем лучше писать активность в кэш и периодически синхронизировать с БД:
php
public function setLastActivity()
{
Cache::put(‘user_activity_’ . $this->id, now(), 600);
}
## Определение онлайн-статуса
После сохранения метки можно легко определить, онлайн ли пользователь:
php
public function isOnline(): bool
{
return $this->last_activity_at
&& $this->last_activity_at->diffInMinutes(now()) timestamps = false` перед сохранением.
— **Отсутствие защиты от гонки** — используйте атомарные операции или кэш.
— **Запись при каждом AJAX-запросе** — применяйте троттлинг.
— **Игнорирование часовых поясов** — всегда храните время в UTC и конвертируйте при отображении.
## Итог
Для корректного обновления `last_activity` при переходах между страницами оптимально комбинировать серверный middleware (для классических приложений) с клиентским хуком роутера (для SPA), применять кэширование для снижения нагрузки на БД и использовать троттлинг для ограничения частоты записи.
