Стратегия отслеживания недавних действий пользователей - PullRequest
9 голосов
/ 06 октября 2008

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

Итак, моя мысль - это 15-минутный интервал для определения активности пользователя. Вот некоторые идеи, которые у меня есть для этого:

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

  2. Отправьте запрос «кто онлайн» из нашего программного обеспечения, ищите ответы, это можно сделать через запланированный промежуток времени, а затем поставьте отметку в записи пользователя с текущей датой и временем для каждого полученного мной ответа.

Что вы думаете? И как бы вы справились с этой ситуацией?

Разъяснение

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

Под Windows я имею в виду клиент-сервер.

Разъяснение

Я использую n-уровневую архитектуру, поэтому мои бизнес-объекты обрабатывают все взаимодействия с уровнем представления. Этот уровень представления может обеспечивать клиент-серверное приложение Windows, веб-приложение, веб-службу и так далее.

Это не приложение с высоким трафиком, так как оно было разработано для наших клиентов, может быть, максимум 100 пользователей.

Ответы [ 12 ]

5 голосов
/ 06 октября 2008

Наше решение состоит в том, чтобы поддерживать таблицу «Транзакция» (которая следует за тем, что было сделано), в дополнение к нашей таблице «Сеанс» (которая следует за тем, кто был здесь). Все инструкции UPDATE, INSERT и DELETE управляются через объект «Transaction», и каждая из этих инструкций SQL сохраняется в таблице «Transaction» после успешного выполнения в базе данных (в зависимости от обновленных таблиц: у нас есть возможность следуйте за некоторыми таблицами и игнорируйте другие). Эта таблица «Transaction» имеет другие поля, такие как TransactionType (I для INSERT, D для DELETE, U для UPDATE), TransactionDateTime и т. Д., И внешний ключ «sessionId», сообщающий, наконец, кто отправил инструкцию. Можно даже с помощью некоторого кода определить, кто что и когда делал (Гас создал запись в понедельник, Тим изменил цену за единицу во вторник, Лиз добавила дополнительную скидку в четверг и т. Д.).

Плюсы для этого решения:

  1. Вы можете сказать «что, кто и когда», и показать это своим пользователям! (вам понадобится код для анализа операторов SQL)
  2. если ваши данные реплицируются, и репликация не выполняется, вы можете перестроить базу данных с помощью этой таблицы

Минусы

  1. 100 000 обновлений данных в месяц означают 100 000 записей в Tbl_Transaction
  2. Наконец, эта таблица, как правило, занимает 99% объема вашей базы данных

Наш выбор: все записи старше 90 дней автоматически удаляются каждое утро

2 голосов
/ 06 октября 2008

Я видел работу стратегии 1 раньше. Конечно сайт был маленький.

1 голос
/ 06 октября 2008

Интересно, как такой сайт, как stackoverflow, делает это?

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

0 голосов
/ 24 марта 2019

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

<?php
function updateLastSeen($user_ref, $session_id, $db) { /*Parameters: The user's primary key, the user's session id, the connection to the database*/
  $timestamp = date('Y-m-d H:i:s');
  if ($session_id !== '') {
    /*logged in*/
    $sql_check = "SELECT user_id FROM user_last_seen WHERE user_id = ?";
    $stmt_check = $db->prepare($sql_check);
    $stmt_check->bind_param('s', $user_ref);
    $result_check = $stmt_check->execute();
    $stmt_result_check = $stmt_check->get_result();
    if ($stmt_result_check->num_rows > 0) { /*If the user's last seen was previously recorded, update his record*/
      $sql = "UPDATE user_last_seen SET last_seen = ? WHERE user_id = ?"; 
    } else { /*Otherwise, insert a record for him*/
      $sql = "INSERT INTO user_last_seen (last_seen, user_id) VALUES (?,?)";
    }
    $stmt = $db->prepare($sql);
    $stmt->bind_param('ss', $timestamp, $user_ref);
    $result = $stmt->execute();
  }
}
if( !isset($_SESSION['lastSeen']) ){ /*User logs into the website or lands on the current page, create a lastSeen variable*/
  $_SESSION['lastSeen'] = time();
  updateLastSeen($user_ref, $session_id, $db);
} else {
  $last_seen_time_difference = (time() - $_SESSION['lastSeen']) / 60;
  if ($last_seen_time_difference > 5) { //if the difference between now and the lastSeen is 5 minutes or more, record his last seen.
    updateLastSeen($user_ref, $session_id, $db);   
    $_SESSION['lastSeen'] = time(); /*after updating the database, reset the lastSeen time to now.*/
  }/* else {
    //do nothing. Don't update database if lastSeen is less than 5 minutes ago. This prevents unnecessary database hits.
  }*/
}
0 голосов
/ 07 октября 2008

С веб-приложением понятие «онлайн» немного туманно. Лучшее, что вы действительно можете сделать, это «сделать запрос за последние X минут» или, может быть, «аутентифицирован за последние X минут».

Выберите набор событий (выполненный запрос, выполненное обновление, аутентифицирован ...) и запишите их в таблицу БД.

Записать их в таблицу в отдельной БД

0 голосов
/ 06 октября 2008

Я полагаю, что использование триггера было бы разумным вариантом, который позволил бы вам не связываться с любыми логическими различиями между веб-и не веб-средой (или любой другой средой в этом отношении). Однако это только фиксирует изменения в среде и ничего не делает, когда выполняются операторы select. Это, однако, может быть преодолено, если все ваши команды из ваших приложений выполняются с помощью хранимых процедур.

0 голосов
/ 06 октября 2008

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

0 голосов
/ 06 октября 2008

[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ 1 --- Java-решение]

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

[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ 2 --- Код не проверен или не скомпилирован]

public class ActiveSessionsListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent e) {
        ServletContext ctx = e.getSession().getServletContext();
        synchronized (ctx) {
            Integer count = ctx.getAttribute("SESSION_COUNT");
            if (count == null) { count = new Integer(0); }
            ctx.setAttribute("SESSION_COUNT", new Integer(count.intValue() + 1);
        }
    }
    public void sessionDestroyed(HttpSessionEvent e) {
        ... similar for decrement ...    
    }
}

И зарегистрируйте это в своем web.xml:

<listener-class>com.acme.ActiveSessionsListener</listener-class>

Надеюсь, это поможет.

0 голосов
/ 06 октября 2008

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

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

0 голосов
/ 06 октября 2008

Если у вас есть данные сеанса, просто используйте их. Большинство систем сеансов уже имеют временные метки, поэтому они могут истекать сеансы, не использованные в течение x минут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...