Стратегия отслеживания недавних действий пользователей

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

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

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

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

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

осветление

Я хотел бы использовать одну и ту же архитектуру как для 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", сообщающий, наконец, кто отправил инструкцию. Можно даже с помощью некоторого кода определить, кто что и когда делал (Гас создал запись в понедельник, Тим изменил цену за единицу во вторник, Лиз добавила дополнительную скидку в четверг и т. Д.).

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

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

Минусы

  1. 100 000 обновлений данных в месяц означают 100 000 записей в Tbl_Transaction
  2. Наконец, эта таблица, как правило, занимает 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) ("внутри" или "вне")
Время ДатаВремя

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

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

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

Другие вопросы по тегам