Как получить пользователей онлайн?

325
24 декабря 2016, 18:41

Сейчас я делаю так: при каждой загрузке страницы, я обновляю в кеше ключ "{$user->id}.online" на 5 мин. Если ключа нет — пользователь не в сети.

Этот способ хорош, когда надо проверить конкретного пользователя зная его id. Но как получить всех пользователей онлайн? Приходится загружать всех юзеров (благо их пока мало) и у каждого проверять "{$user->id}.online". Это ужасно. Есть ли способ лучше?

Answer 1

Можно попробовать вычислить с помощью сессий.

Для сессий по умолчанию определено файловое хранение, где каждый сеанс индивидуально хранится на диске. Это означает, что для того чтобы выяснить сколько пользователей online (я предполагаю, "online = набор существующих сессий $_SESSION['$nickname']), вам нужно будет открыть все файлы сессий, сохраненные на диске, и проверить, сколько уникальных nicknam'ов существуют внутри сессий.

Стоит учитывать что:

  • Сессии не разрушаются сразу при закрытии браузера. Это означает, что сервер должен придумать какой-то алгоритм на основе времени, чтобы решить, кто в сети, а кто нет.
  • Сеансы изолированы друг от друга так что $_SESSION["test1"] не может совместно использоваться несколькими другими сессиями.
Answer 2

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

$m = new Memcached();
$m->addServer('localhost', 11211);
$now = time();
$life = 5 * 60;
$m->set("{$user->id}.online", true, $life);
if (($online_users = $m->get('online_users')) === false) {
    $online_users = array($user->id => $now);
    // нужно ли записывать время в значение элемента под вопросом
    // возможно хватит true или 1   
} else {
    $online_users[$user->id] = $now;
    foreach ($online_users as $id => $time) {
        // ключи {$id}.online остаются для проверки
        if (false === $m->get("{$id}.online")) {
            unset($online_users[$id]);
        } else {
            // тут что-то делаем с юзером, который онлайн
            // $id содержит его номер
            // $time содержит время последней отметки оналайн
        }
    }
}
$m->set('online_users', $online_users, $life);
// в переменной $online_users массив id (номера в ключах массива) юзеров онлайн

P.S. Тестирование не проводилось. Выгоды/проигрыши не вычислялись.

Answer 3

Табличка в БД с двумя полями

CREATE TABLE users{
    user_id INT,
    last_login TIMESTAMP,
    PRIMARY KEY(user_id)
}

При входе пользователя

INSERT INTO users (user_id, last_login) values ($id, NOW()) ON DUPLICATE KEY UPDATE last_login=NOW();

Соответственно, количество "активных"

SELECT COUNT(*) FROM users WHERE NOW() - last_login<$desired_timeout
READ ALSO
Как работает такая конструкция public function Name (Closure $closure){}

Как работает такая конструкция public function Name (Closure $closure){}

Вызывают в начале кода use Closure; это есть внутренний класс php Closure а далее используют внутри функции переменную $closure; из мануала совершенно не понятно...

387
Навигация по сайту с помощью клавиатуры

Навигация по сайту с помощью клавиатуры

Необходимо создать навигацию по сайту, к примеру с помощью клавиши пробел или shift+стрелка выделять первый элемент на странице, а если фокус...

443
example api vine javascript

example api vine javascript

Я тут сутки не спал, поэтому помогите мне подумать

396