Наш клиент хотел бы знать, что кто находится в сети и в настоящее время использует пользовательское приложение, которое мы для него написали. Я обсуждал это с ними, и это не обязательно должно быть точный, более приблизительная оценка будет работать.
Итак, я думаю, что для определения активности пользователя требуется 15-минутный интервал времени. Вот некоторые идеи, которые у меня есть для этого:
Пометить свою пользовательскую запись датой и временем их последнего действия каждый раз, когда они делают что-то, что попадает в базу данных или запрашивает веб-страницу ... хотя это может быть довольно интенсивным для базы данных.
Отправьте из нашего программного обеспечения «кто сейчас находится в сети», ищите ответы, это можно сделать с заданным интервалом, а затем отметьте запись пользователя с текущей датой и временем для каждого полученного мной ответа.
о чем ты думаешь? И как бы вы справились с этой ситуацией?
Разъяснение
Я хотел бы использовать одну и ту же архитектуру как для Windows, так и для Интернета, если это возможно. У меня есть один уровень бизнес-логики, с которым взаимодействуют несколько пользовательских интерфейсов, будь то Windows или Интернет.
Под Windows я бы имел в виду клиент-сервер.
Разъяснение
Я использую многоуровневую архитектуру, поэтому мои бизнес-объекты обрабатывают все взаимодействия с уровнем представления. Этот уровень представления может питать клиент-серверное приложение Windows, веб-приложение, веб-службу и т. д.
Это не очень загруженное приложение, так как оно было разработано для нашего клиента, максимум 100 пользователей.
согласен, это веб-приложение или нет?
Если бы я мог заставить его работать для клиент-сервера и веб-приложения, это было бы лучше всего.

Я уже видел, как работает стратегия 1. Конечно, сайт был маленьким.
Я бы просто сбросил таблицу записей журнала в базу данных.
UserId int FK
Знак действия (3) («вход» или «выход»)
Время Дата Время
Вы можете удалить новую запись в таблице, когда кто-то входит в систему или выходит из нее, или, в качестве альтернативы, обновить последнюю запись для пользователя.
Я работал со многими системами, в которых использовался первый метод, который вы перечислили, и при небольшом тщательном планировании это можно сделать так, чтобы это не дало особого эффекта.
Все зависит от того, когда / как / что вы пытаетесь отслеживать. Если вам нужно отслеживать несколько сеансов, я обычно вижу людей, которые используют систему сеансов, привязанную к учетной записи пользователя, а затем по истечении определенного времени этот сеанс считается мертвым.
Если вы действительно ищете онлайн, ваш первый вариант будет лучшим.
Если у вас есть данные сеанса, просто используйте их. У большинства систем сеансов уже есть отметки времени, поэтому они могут истекать сеансы, которые не использовались в течение 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>
Надеюсь это поможет.
Единственная проблема с решением веб-приложения заключается в том, что вы часто не знаете, когда кто-то выходит из системы. Очевидно, что если у вас есть требование входа в систему / аутентификации, вы можете фиксировать, когда человек входит в систему, и как часть вашего кода доступа к данным вы можете регистрировать, когда человек попадает в базу данных. Но вам придется согласиться с тем, что будет надежный способ захвата, когда человек выходит из системы - многие просто уйдут с сайта, не выполняя действие «выйти из системы».
Я бы предположил, что использование триггера было бы разумным вариантом, который избавит вас от необходимости связываться с любыми логическими различиями между веб-средой и не-веб-средой (или любой другой средой в этом отношении). Однако это только фиксирует изменения в среде и ничего не делает при выполнении операторов выбора. Однако это можно преодолеть, если все ваши команды из ваших приложений запускаются через хранимые процедуры.
Интересно, как это делает такой сайт, как stackoverflow?
Они должны быть нацелены на конкретное событие, так как я только что изучил сайт, взглянул на свой профиль и все равно сказал что-то вроде был в Сети 8 минут назад.
Результаты моего ответа дают это, за исключением того, что мое пособие установлено на 5 минут.
Наше решение состоит в том, чтобы поддерживать таблицу «Транзакция» (которая следует за тем, что было сделано), в дополнение к нашей таблице «Сессия» (которая следует за тем, кто здесь был). Инструкции UPDATE, INSERT и DELETE управляются через объект «Транзакция», и каждая из этих инструкций SQL сохраняется в таблице «Транзакция» после того, как она была успешно выполнена в базе данных (в зависимости от обновленных таблиц: у нас есть возможность специально следуйте одним таблицам и игнорируйте другие). В этой таблице «Transaction» есть другие поля, такие как transactiontType (I для INSERT, D для DELETE, U для UPDATE), transactionDateTime и т.д., а также внешний ключ «sessionId», сообщающий нам, наконец, кто послал инструкцию. С помощью некоторого кода можно даже определить, кто что и когда сделал (Гас создал запись в понедельник, Тим изменил цену за единицу во вторник, Лиз добавила дополнительную скидку в четверг и т. д.).
Плюсы этого решения:
Минусы
Наш выбор: все записи старше 90 дней автоматически удаляются каждое утро
С веб-приложением понятие «онлайн» немного расплывчато. Лучшее, что вы действительно можете сделать, - это «сделать запрос за последние 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.
}*/
}
Стратегия для этого может быть совершенно разной в зависимости от того, является ли это веб-приложение / клиент-сервер и т. д. - Я думаю, нам нужно немного больше деталей о задействованном стеке / архитектуре.