Как узнать, находится ли пользователь в сети на веб-сайте с базами данных, управляемыми php и mysql?

Я создаю сайт сообщества. Пользователи будут входить и выходить из системы, как обычно.

Я использую статус атрибута онлайн/офлайн, чтобы установить статус пользователя. Но что, если пользователь просто нажмет кнопку X или иным образом отключится, не выходя из системы?

Недавно мой компьютер сломался, когда я открыл сайт на своем ноутбуке, я не смог войти в систему, потому что я не разрешаю вход в два места. Я захожу в PHPMyAdmin и вижу, что мой статус все еще онлайн. Есть ли какое-либо решение для этого.

Я пробовал операцию last_time, но она не работает в случае сбоя компьютера! И не было ничего ни интерактивности, ни рефреша для обновления таблицы.


person aygeta    schedule 06.11.2011    source источник


Ответы (12)


Вам не нужен флаг онлайн/офлайн, вам просто нужно сохранить время последней активности. При отображении статуса пользователя, если время последней активности меньше, чем сейчас + 15 минут, то пользователь находится в сети, в противном случае - в автономном режиме.

person Volodymyr Smotesko    schedule 06.11.2011

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

У вас может быть сценарий (AJAX), проверяющий каждые X минут, чтобы увидеть, отвечает ли браузер, и если нет, переключиться в автономный режим, но это потребует дополнительных ресурсов. Вот как, например, работает IRCd: они пингуют вас, вы отвечаете PONG. Если вы не ответите, у вас истечет время ожидания и вы отключитесь от сервера.

HTTP не имеет состояния, другого встроенного решения нет. Может быть, HTML5 и сокеты, но это будет тот же принцип, что и простой AJAX.

person Konerak    schedule 06.11.2011
comment
Так что теперь я ничего не могу сделать. Я просто могу сидеть и смотреть, как злятся мои пользователи :) Это плохо. Как я могу реализовать это с помощью ajax? Разве этот метод не зависит от того, взаимодействует ли пользователь с сайтом. Разве это не javascript-сторона кодирования? Если это так, пользователь должен получить доступ к моему сайту, чтобы взаимодействовать с ajax :) - person aygeta; 06.11.2011
comment
Вы реализуете функцию «последний раз видели менее X минут». Это работает. Теперь, чтобы повысить надежность функции, уменьшите X и заставьте пользователей взаимодействовать каждые X/2-(1 мс), используя, например, AJAX. - person Konerak; 06.11.2011
comment
Ответ, помеченный как правильный, предлагает практическое решение, противоречащее вашему утверждению. - person zardilior; 21.07.2016

Вы можете запускать функцию для каждого запроса страницы, которая обновляет строку в вашей базе данных с вашим идентификатором пользователя и расчетной временной меткой на будущее (например, time()+(60*5); - пять минут). Затем всякий раз, когда другой пользователь пытается проверить, находится ли первый пользователь в сети, вы можете проверить его по базе данных, используя «импульсную» проверку:

$time = time();
$query = mysql_query("SELECT user_id, timestamp FROM online_users WHERE user_id = '$user_id' AND timestamp > '$time'");

Если этот запрос возвращает более 0 строк, считается, что пользователь находится в сети.

person Seralize    schedule 06.11.2011

Надуманное решение.

Используйте сервер node.js с socket.io. Попросите клиента подключиться к серверу через клиентскую часть socket.io. Сервер отвечает за отправку событий клиентам и ожидание ответа. При отключении или позднем ответе помечайте пользователя как не в сети.

Это будет работать и, вероятно, будет работать даже при отключении кабеля/закрытии браузера, но стоит ли оно усилий?

person mobius    schedule 06.11.2011

Вы можете использовать этот метод: 1. проверьте статус пользователя, если он в сети, проверьте последнюю активность, если она более 10 минут, установите статус в автономном режиме, если она менее 10 минут, покажите, пока пользователь не в сети, если он не в сети, покажите пользователя в автономном режиме.

  1. Когда пользователь, использующий этот сайт, обновляет последнюю активность каждые «x» минут с помощью ajax
  2. Когда пользователь нажимает на выход, установите статус в автономном режиме. Это может быть ваша структура базы данных.

введите здесь описание изображения

person Mostak Shahid    schedule 04.05.2016

Вы на правильном пути: сохраните UNIX-время последней активности пользователя в базе данных и, когда кто-то заходит на сайт, установите статус не в сети для пользователей, которые не были активны в течение 15 минут (или меньше) . Если пользователь вошел в систему и его статус в базе данных установлен на не в сети, принудительно выйти из системы (уничтожив сеанс).

Однако главный вопрос: стоит ли оно того? Я еще не видел подобной системы аутентификации.

person Alessandro Desantis    schedule 06.11.2011
comment
Эй, я что-то не понимаю. Способны ли базы данных подсчитывать или видеть пользователей last_activity без взаимодействия с пользователем? Или сказать, если пользователь ничего не делает в базе данных. Считает ли база данных время самостоятельно, и если она видит, что пользователь не был активен в течение половины времени, чтобы обновить таблицу и установить статус в автономном режиме? Может ли это произойти без взаимодействия с пользователем. Если это так, я могу использовать базы данных, чтобы увидеть last_activity и обновить таблицу без взаимодействия с пользователем. - person aygeta; 06.11.2011
comment
Нет, сама база данных не может определить активность пользователя. Вы должны обновлять поле в таблице пользователей при каждом запросе на страницу вашего сайта. Было бы проще, если бы у вас был передний контроллер. Ты? - person Alessandro Desantis; 06.11.2011
comment
У меня виртуальный хостинг. Я не могу установить контроллер, который будет работать в фоновом режиме. Как они это делают? как это делают форумы досок объявлений? Как это делают другие сайты? Должно быть что-то, чтобы сделать это. Что, если пользователь просто выключит компьютер. Что тогда ? как я могу обновить таблицу. :( - person aygeta; 06.11.2011
comment
Фронт-контроллер означает, что пользователь получает доступ только к одной странице вашего сайта, и PHP-скрипт позаботится о возврате соответствующего ответа. Например, /index.php?page=foo вместо /foo.php. Таким образом, вы можете разместить код для обновления активности пользователя только в файле index.php, а не в файле foo.php. - person Alessandro Desantis; 06.11.2011
comment
Нет, я этого не делаю. Я использую классы и больше ajax, чтобы делать большинство вещей. Но эй, пожалуйста, прочтите это -› Что, если пользователь просто выключит компьютер? Нет никакого взаимодействия, ничего, просто ничего. Как я буду обновлять свою таблицу? - person aygeta; 06.11.2011
comment
Когда следующий посетитель зайдет на сайт, ваш PHP-скрипт автоматически уничтожит сеанс, если в течение 15 минут не было никакой активности. - person Alessandro Desantis; 06.11.2011
comment
Как я могу уничтожить сеанс других пользователей? с этим новым пользователем? Я действительно не понимаю. Как можно обновить статус этого пользователя от другого пользователя? - person aygeta; 06.11.2011
comment
Под уничтожением сеанса я подразумеваю установку статуса offline в базе данных. - person Alessandro Desantis; 06.11.2011
comment
Хорошо, теперь я понимаю. Когда новый пользователь заходит на мой сайт. Я должен запрограммировать скрипт, который проверит все атрибуты last_activity в моей таблице и увидит, было ли last_activity до 30 минут, а затем обновит этот атрибут состояния до автономного. Затем каждый пользователь заходит на мой сайт, этот скрипт также будет запускаться для получения last_activity. С этим я могу обновить строку любого пользователя другими пользователями. понял, сейчас попробую - person aygeta; 06.11.2011

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

Как упомянул Конерак, HTTP не имеет состояния и не имеет встроенного способа определить, покинул ли кто-то ваш сайт. Вы могли бы выяснить это с помощью какой-либо техники опроса на основе JavaScript, но это вызвало бы много накладных расходов, которые просто не нужны в большинстве ситуаций.

Вместо этого вы должны отслеживать время последней активности пользователя и сохранять это время в своей базе данных или, что еще лучше, в чем-то вроде кэш памяти. Если время последней активности пользователя превышает период тайм-аута, который вы выбрали, предположим, что он больше не находится на сайте.

Вторая часть заключается в том, чтобы вместо отказа в входе в систему, когда кто-то пытается войти после ухода с сайта без выхода из системы, разрешить им войти в систему и аннулировать все старые сеансы, связанные с их учетной записью.

person Useless Code    schedule 07.11.2011

подождите, чувак, я думаю, что у меня есть правильный ответ, потому что я столкнулся с той же проблемой! попробуйте использовать событие мыши [click, movemouse ..], но с задержкой, чтобы не вызвать сбой в навигаторе, вы будете использовать setInterval через xx секунд или минут после того, как сохраните ответ на событие в свою базу данных в столбце активности, но со временем unix, чтобы отличать его позже от настоящего времени.. это действительно полезно, я использовал его для регистрации активности участников, чтобы знать, что они на самом деле делают в режиме реального времени, а также получать пользователей онлайн / офлайн. вот используемые функции js:

var body = document.getElementById('body');
var url = './member-activity.php?loggedUser=<?=$memb_id?>&curl=<?=($_SERVER['QUERY_STRING'])?>';
if(document.addEventListener) {
  document.addEventListener("click", _EventLogging, false);
    document.addEventListener("mousemove", _EventLogging, false);
}else{
  document.attachEvent("onclick", _EventLogging);
}
function _EventLogging(){
//call it after a delay of 
setTimeout(AjaxUrl(url), 2000); //delay of 2 sec after every move of cursor
}
//AjaxUrl is a js function that calls a php file to perform the activity logging via AJAX
</script>
<div id="id"></div>

div выше должен уведомлять вас об ошибках в коде, вы удалите его, когда все в порядке! я надеюсь, что мой ответ был правильным для вашего случая //[email protected]

person user1998704    schedule 22.01.2013

Что ж, реальный ответ на ваш вопрос «Как мне обновить таблицу без взаимодействия с пользователем?»

является планировщиком событий MySql, вы планируете выполнение события (запроса) в любое время, даже если пользователь находится в автономном режиме, читайте об этом здесь (http://dev.mysql.com/doc/refman/5.1/en/events-overview.html)

person EvilThinker    schedule 04.05.2013

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

person ps374    schedule 05.06.2018

на самом деле единственный правильный способ сделать это — использовать websocket, он будет общаться с пользователем в режиме реального времени, попробуйте Храповик.

person shamaseen    schedule 06.02.2020

В соответствии с вашим сценарием вы можете использовать приведенную ниже логику для проверки статуса пользователя:

Вместо того, чтобы проверять, находится ли пользователь в сети или в автономном режиме только в зависимости от значения столбца таблицы, также используйте переменную сеанса. например, рассмотрим приведенный ниже код:

 <?php

  $stauts_from_table_column;

  if($stauts_from_table_column==1 && isset($_SESSION['userid']))
  {
   $user_logged_in = true;
  }
  else
  {
   $user_logged_in = false;
  }     

?>

Вы можете улучшить его дальше, но вы поняли мою точку зрения, я надеюсь.

person Ghost-Man    schedule 06.11.2011
comment
Люди, пожалуйста, прочитайте мой вопрос. Как я буду обновлять таблицу без взаимодействия с пользователем. Что, если пользователь просто выключит компьютер??? Нет никакого взаимодействия, чтобы обновить таблицу, ничего, ничего. Что теперь ? - person aygeta; 06.11.2011
comment
@aygeta Для автоматического обновления базы данных вы можете запустить на сервере задание CRON, которое запускается каждую минуту и ​​в зависимости от времени последней активности пользователя будет обновлять поле столбца. Другой способ без задания cron: в следующий раз, когда пользователь попытается войти в систему, вы проверяете, не установлен ли SESSION и установлен ли он в базе данных. После аутентификации обновите его соответствующим образом. - person Ghost-Man; 06.11.2011