PHP - как определить дату и время окончания сеанса?

Usercase: мне нужно отслеживать продолжительность пребывания пользователя на сайте. Это рассчитывается как (дата-время окончания - дата-время начала). Это отлично работает, если пользователь нажимает «Выход». затем система может записать дату и время окончания. Но у меня проблема в крайних случаях: сеанс пользователя заканчивается из-за - потери интернет-соединения на стороне пользователя, закрытия браузера, сбоя системы и т. д. В этих случаях, как система узнает дату и время окончания, чтобы я мог рассчитать продолжительность. Необходимо, чтобы дата и время окончания были рассчитаны как можно ближе к реальному времени и дате. Если это невозможно, то до 5 минут точного времени вполне достаточно.

Один из возможных способов, который я вижу, - это продолжать пинговать клиентскую систему и проверять, активна она или нет. Но я не хочу этого делать, так как это добавляет нежелательную пропускную способность. Итак, есть ли другой способ получить эту информацию для крайних случаев?


person SeanD    schedule 25.01.2011    source источник
comment
Самый простой способ — увеличивать поле времени активности в базе данных каждый раз, когда пользователь запрашивает страницу. Или пользовательский обработчик сеанса, который сам по себе беспорядок. Я надеюсь, что вы не хотите добавлять тайм-аут сеанса к времени активности, хотя   -  person Your Common Sense    schedule 25.01.2011
comment
запрос страницы не помогает, поскольку такие страницы, как новостные ленты, остаются открытыми в течение всего дня. Так что срез времени будет не точен.   -  person SeanD    schedule 29.01.2011


Ответы (3)


Почему бы просто не проверить время последнего просмотра страницы?

Проверка времени открытия окна браузера мало что даст таким людям, как я, которые любят оставлять вкладки открытыми... Не говоря уже о том, что будет довольно сложно охватить все крайние случаи (браузеры, которые не поддерживают JS, люди за прокси и т. д.). Время последнего просмотра страницы должно быть точным до нескольких минут, и оно будет иметь наименьшие накладные расходы/сложность, сохраняя при этом достойный уровень точности...

person ircmaxell    schedule 25.01.2011
comment
Что ж, проблема в том, что, скажем, ваша страница в прямом эфире. (например, ваша домашняя страница в Facebook) люди держат ее открытой почти весь день на этой странице. Так что мой последний просмотр мог быть 2 часа назад, что не точно. - person SeanD; 25.01.2011
comment
@seanD: Ну, тогда у вас будут вызовы Ajax, которые должны обновить сеанс, не так ли? И если пользователь переключает вкладки, вы не можете этого сказать (ну, вы могли бы определить смену вкладок, чтобы попытаться получить еще более точное время, если пользователь отключится). Но в зависимости от ваших требований вы можете слишком усложнять вещи, когда простого HTTP-трафика достаточно, чтобы сообщить вам то, что вам нужно знать. - person ircmaxell; 25.01.2011

На практике система никогда не может знать время окончания, потому что HTTP по своей сути является протоколом без сохранения состояния. Сеансы PHP (и аналогичные функции в других языках веб-скриптов) — это хак для реализации чего-то, что кажется с сохранением состояния, но такие хаки не могут полностью преодолеть природу HTTP без сохранения состояния. Например, как вы обнаружили, сервер не может узнать, что пользователь вышел из системы, если он не прошел процесс «выхода из системы».

Вы можете использовать AJAX для проверки связи пользователя, но, как вы сказали, это использует пропускную способность. Он также не будет работать, если у пользователя отключена поддержка javascript.

Единственный другой разумный вариант — регистрировать временную метку для пользователя каждый раз, когда он попадает на страницу в вашей системе, и смотреть, сколько времени прошло с момента обновления временной метки. Если оно превышает разумный предел, скажем, 20 минут, то можно сделать предположение, что пользователь больше не находится на вашем сайте. Опять же, это не совсем идеально, так как пользователь мог просто выйти покурить или что-то в этом роде, но, поскольку HTTP не имеет состояния, никакое решение, которое вы можете реализовать, не является полностью идеальным.

person GordonM    schedule 25.01.2011
comment
я могу пропинговать пользователя один раз в 10 минут, я думаю, что даст мне точность 9 минут 59 секунд, по крайней мере. Это социальный сайт, поэтому люди могут сидеть на нем весь день на одной и той же странице, читая обновления ленты. На сайте требуется Javascript. Если они выяснят это, им будет заблокирован вход на сайт. - person SeanD; 29.01.2011

Отслеживайте время последней активности сеанса пользователя - в основном при каждом клиентском запросе вы обновляете запись сеанса со временем запроса. Если вы также сохранили время входа в систему, вы всегда можете рассчитать продолжительность сеанса, независимо от того, активен он, неактивен или пользователь вышел из системы. Я также поместил флаг logged_out в свои таблицы сеансов, который устанавливается, если пользователь активно выходит из системы.

Вот определение моей таблицы сеансов:

CREATE TABLE IF NOT EXISTS `session` (
  `id` int(11) NOT NULL auto_increment,
  `php_session_id` varchar(100) NOT NULL default '',
  `ip_addr` varchar(100) NOT NULL default '',
  `login_time` datetime NOT NULL ,
  `activity_time` datetime NOT NULL ,
  `user_id` int(11) NOT NULL default '0',
  `logged_out` tinyint(1) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `session_id` (`php_session_id`,`ip_addr`),
  KEY `user` (`user_id`,`logged_out`)
) ;
person james-geldart    schedule 25.01.2011
comment
нет, это просто индексы. «KEY» и «INDEX» взаимозаменяемы в определениях таблиц MySQL. - person james-geldart; 16.02.2011