Стратегия отслеживания недавних действий пользователей
Наш клиент хотел бы знать, кто в сети и в настоящее время использует пользовательское приложение, которое мы для него написали. Я обсуждал это с ними, и это не должно быть точным, более сметная оценка сработает.
Так что моя мысль - это 15-минутный интервал времени для определения активности пользователя. Вот некоторые идеи, которые у меня есть для этого:
Отметьте в своей записи пользователя дату и время их последнего действия каждый раз, когда они делают что-то, что попадает в базу данных или запрашивает веб-страницу... хотя это может быть довольно интенсивно в базе данных.
Отправьте запрос "кто онлайн" из нашего программного обеспечения, ищите ответы, это можно сделать через определенный промежуток времени, а затем отметьте в записи пользователя текущую дату и время для каждого полученного мной ответа.
о чем ты думаешь? И как бы вы справились с этой ситуацией?
осветление
Я хотел бы использовать одну и ту же архитектуру как для Windows, так и для Интернета, если это возможно. У меня есть один уровень бизнес-логики, с которым взаимодействуют несколько пользовательских интерфейсов, может быть Windows или Интернет.
Под Windows я имею в виду клиент-сервер.
осветление
Я использую n-уровневую архитектуру, поэтому мои бизнес-объекты обрабатывают все взаимодействие с уровнем представления. Этот уровень представления может обеспечивать клиент-серверное приложение Windows, веб-приложение, веб-службу и так далее.
Это не приложение с высоким трафиком, так как оно было разработано для нашего клиента, может быть, максимум 100 пользователей.
11 ответов
Наше решение состоит в том, чтобы поддерживать таблицу "Transaction" (которая следует за тем, что было сделано), в дополнение к нашей таблице "Session" (которая следует за тем, кто был здесь). Все инструкции UPDATE, INSERT и DELETE управляются через объект "Transaction", и каждая из этих инструкций SQL сохраняется в таблице "Transaction" после успешного выполнения в базе данных (в зависимости от обновленных таблиц: у нас есть возможность следуйте за некоторыми таблицами и игнорируйте другие). Эта таблица "Transaction" имеет другие поля, такие как TransactionType (I для INSERT, D для DELETE, U для UPDATE), TransactionDateTime и т. Д., И внешний ключ "sessionId", сообщающий, наконец, кто отправил инструкцию. Можно даже с помощью некоторого кода определить, кто что и когда делал (Гас создал запись в понедельник, Тим изменил цену за единицу во вторник, Лиз добавила дополнительную скидку в четверг и т. Д.).
Плюсы для этого решения:
- Вы можете сказать "что, кто и когда", и показать это своим пользователям! (вам понадобится код для анализа операторов SQL)
- если ваши данные реплицируются, и репликация не выполняется, вы можете перестроить базу данных с помощью этой таблицы
Минусы
- 100 000 обновлений данных в месяц означают 100 000 записей в Tbl_Transaction
- Наконец, эта таблица, как правило, занимает 99% объема вашей базы данных.
Наш выбор: все записи старше 90 дней автоматически удаляются каждое утро
Я видел стратегию 1 работы раньше. Конечно сайт был маленький.
Интересно, как сайт вроде stackru это делает?
Они должны быть нацелены на определенное событие, так как я только что просмотрел сайт, посмотрел на мой профиль и все еще говорит что-то вроде того, что в последний раз видели 8 минут назад.
Я работал со многими системами, которые использовали первый метод, который вы перечислили, с небольшим тщательным планированием, это может быть сделано способом, который действительно не имеет большого эффекта.
Все зависит от того, когда именно / как / что вы пытаетесь отследить. Если вам нужно отслеживать несколько сеансов, я обычно вижу людей, которые используют систему сеансов, привязанную к учетной записи пользователя, а затем к определенному истекшему времени, когда сеанс считается мертвым.
Если вы действительно ищете в настоящее время онлайн, ваш первый вариант является лучшим.
Я полагаю, что использование триггера было бы разумным вариантом, который позволил бы вам не связываться с любыми логическими различиями между веб-и не-веб-средой (или любой другой средой в этом отношении). Однако это только фиксирует изменения в среде и ничего не делает, когда выполняются операторы select. Это, однако, может быть преодолено, если все ваши команды из ваших приложений выполняются с помощью хранимых процедур.
Если у вас есть данные сессии, просто используйте это. Большинство систем сеансов уже имеют временные метки, поэтому они могут истекать сеансы, не использованные в течение x минут.
[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ 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>
Надеюсь это поможет.
Единственная проблема с решением веб-приложения - вы часто не знаете, когда кто-то выходит из системы. Очевидно, что если у вас есть требование входа в систему / аутентификации, вы можете регистрировать, когда человек входит в систему, и, как часть вашего кода доступа к данным, вы можете регистрировать, когда человек попадает в базу данных. Но вам придется согласиться с тем, что при выходе из системы будет надежный способ захвата - многие просто уйдут с сайта, не предпринимая действия "выйти из системы".
С веб-приложением понятие "онлайн" немного туманно. Лучшее, что вы действительно можете сделать, это "сделать запрос за последние X минут" или, может быть, "аутентифицироваться за последние X минут".
Выберите набор событий (выполненный запрос, выполненное обновление, проверка подлинности, ...) и зарегистрируйте их в таблице БД.
Записать их в таблицу в отдельной БД
Я только что внедрил последнюю систему для моего сайта. Ваш первый вариант похож, но я обновляю только каждые +-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.
}*/
}
Я бы просто сбросил таблицу записей журнала в БД.
UserId int FK
Действие char(3) ("внутри" или "вне")
Время ДатаВремя
Вы можете удалить новую запись в таблице, когда кто-то войдет в систему или выйдет из нее, или, в качестве альтернативы, обновить последнюю запись для пользователя.
Вы можете увеличивать глобальную переменную каждый раз, когда создается сеанс пользователя, и уменьшать ее, когда она уничтожается. Таким образом, вы всегда будете знать, сколько пользователей онлайн в любой момент.
Если вы хотите отслеживать его с течением времени, с другой стороны, я думаю, что начало и конец сеанса ведения журнала в базе данных - это лучший вариант, и вы вычисляете активность пользователя по факту простым запросом.