跟踪用户最近活动的策略
-
05-07-2019 - |
题
我们的客户想知道谁在线并且目前正在使用我们为他们编写的自定义应用程序。我和他们讨论过这个问题并不需要准确,更多的猜测会起作用。
所以我的想法是15分钟的时间间隔来确定用户活动。我这样做的一些想法如下:
-
每次用户操作上一次活动的日期和时间标记他们的用户记录,或者请求网页......这可能是数据库密集型的。
-
发送“谁是在线请求”从我们的软件中寻找响应,这可以按计划的时间间隔完成,然后在用户记录上标记我收到的每个响应的当前日期和时间。
醇>
你有什么想法?你会如何处理这种情况?
<强>澄清强>
如果可能的话,我想在Windows或Web上使用相同的架构。我有一个业务逻辑层,多个用户界面可以与之交互,可以是Windows或Web。
通过Windows,我的意思是客户端服务器。
<强>澄清强>
我使用的是n层架构,因此我的业务对象处理与表示层的所有交互。该表示层可以提供客户端 - 服务器Windows应用程序,Web应用程序,Web服务等。
它不是一个高流量的应用程序,因为它是为我们的客户开发的,最多可能有100个用户。
解决方案
我们的解决方案是维持“交易”。除了我们的“会话”之外,该表(遵循已完成的内容)表(跟随谁在这里)。 UPDATE,INSERT和DELETE指令都通过“事务”管理来管理。对象和这些SQL指令中的每一个都存储在“事务”中。表一旦在数据库上成功执行(取决于更新的表:我们有可能专门遵循一些表并忽略其他表)。这个“交易” table具有其他字段,例如transactiontType(I表示INSERT,D表示DELETE,U表示UPDATE),transactionDateTime等,以及外键“sessionId”,最后告诉我们谁发送了指令。通过一些代码甚至可以确定谁做了什么以及何时做(Gus在星期一创建了记录,Tim在星期二改变了单价,Liz在星期四增加了额外的折扣等)。
此解决方案的优点是:
- 您可以告诉“谁和何时”,并向您的用户展示! (你需要一些代码来分析SQL语句)
- 如果您的数据被复制,并且复制失败,您可以通过此表重建数据库 醇>
- 每月100 000次数据更新意味着Tbl_Transaction 中有100 000条记录
- 最后,此表往往是数据库卷的99% 醇>
缺点
我们的选择:所有超过90天的记录都会每天早上自动删除
其他提示
我之前看过战略1的工作。当然这个网站很小。
我想知道像stackoverflow这样的网站是怎么做到的?
他们必须定位一个特定的事件,因为我刚刚在网站上工作,看看我的个人资料,并且仍然说出像最后一次见到8分钟之前。
我只是在db中删除一个日志记录表。
UserId int FK
动作char(3)('in'或'out')
时间日期时间
当有人登录或退出或者更新用户的最后一条记录时,您可以在表格中删除新记录。
如果您有会话数据,请使用它。大多数会话系统已经有时间戳,因此它们可以使不用于x分钟的会话到期。
您可以在每次创建用户会话时递增全局变量,并在销毁时递减它。通过这种方式,您将始终了解在任何特定时刻有多少用户在线。
另一方面,如果你想监视它,我认为记录会话开始和结束数据库是最好的选择,你可以用简单的查询计算用户活动。
[免责声明1 --- Java解决方案]
如果为每个有意义的用户提供了一个Session,那么您可以编写自己的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>
希望这有帮助。
Web应用程序解决方案的唯一问题是您经常不知道何时有人注销。显然,如果您有登录/身份验证要求,则可以在人员登录时捕获,并且作为数据访问代码的一部分,您可以在人员访问数据库时进行记录。但是你必须接受当一个人注销时会有可靠的捕获方法 - 许多人只是离开了网站而没有取消“注销”。动作。
我认为使用触发器是一个合理的选择,可以防止您不得不弄乱Web和非Web环境(或任何其他环境)之间的任何逻辑差异。但是,这仅捕获对环境的更改,并且在生成select语句时不执行任何操作。但是,如果应用程序中的所有命令都是通过存储过程运行的,则可以解决此问题。
使用网络应用程序,“在线”的概念有点模糊。你真正做的最好的事情是“在最后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(我刚刚为我的网站实现了最后一次看到的系统。您的第一个选项类似,但我每隔+5分钟更新一次。它适用于我的情况,但规模较大的网站可能需要一些额外的东西。
<*>SESSION['lastSeen']) ){ /*User logs into the website or lands on the current page, create a lastSeen variable*/
我刚刚为我的网站实现了最后一次看到的系统。您的第一个选项类似,但我每隔+5分钟更新一次。它适用于我的情况,但规模较大的网站可能需要一些额外的东西。
<*>SESSION['lastSeen'] = time();
updateLastSeen($user_ref, $session_id, $db);
} else {
$last_seen_time_difference = (time() - 我刚刚为我的网站实现了最后一次看到的系统。您的第一个选项类似,但我每隔+5分钟更新一次。它适用于我的情况,但规模较大的网站可能需要一些额外的东西。
<*>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);
我刚刚为我的网站实现了最后一次看到的系统。您的第一个选项类似,但我每隔+5分钟更新一次。它适用于我的情况,但规模较大的网站可能需要一些额外的东西。
<*>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.
}*/
}