5

在 ASP.NET 站点上,有哪些技术可用于跟踪在任何给定时间点登录到站点的用户数量?

因此,例如,我可以生成一个显示如下内容的报告:

        10:00am  11:00am  12:00pm  1:00pm  2:00pm ....
 3/25      25      32       45      40      37
 3/26      31      38       50      57      40
 3/27      28      37       46      35      20
 etc. 

编辑:不,我们没有使用 ASP.NET 成员资格提供程序,它使用基于本地/hacky 会话的方法来确定用户是否处于“登录”状态。

4

9 回答 9

8

网站是否让用户登录?如果是这样,那么您可以在每次用户请求新页面时更新用户表中的“上次访问”字段,然后每隔一小时,只需执行一个 SQL 查询,该查询会获取在最后一次访问中具有“上次访问”时间戳的每个人15 分钟左右(假设当前在站点上)。

如果你没有人登录,你可以很容易地通过 IP 地址而不是用户名来登录。但是,使用这种方法,您可能会遇到一些代理问题(即,来自同一公司网络的多个用户可能都来自一个 IP 地址,因此在您的总数中他们只计为一个用户),但这应该是最小的。

于 2009-03-26T14:24:48.553 回答
3

这种类型取决于您的网站。如果您使用 ASP.Net Membership Providers 有一个方法:Membership.GetNumberOfUsersOnline()它可以告诉您有多少登录用户。我相信也有性能计数器。登录用户的概念是在过去 x 分钟内做了某事的用户,其中 x 是可配置的。

如果您想了解有多少活动,您还可以使用性能计数器来跟踪传入的请求。

编辑

就像您知道 SQL ASP Membership 提供程序通过在数据库中的字段上记录活动日期来实现这一点一样。它只是在 x 分钟内查询所有活动。

我添加了一个客户端轮询功能,它每 2 分钟访问一次我们的服务器,因此当用户坐在页面上时,即使没有活动,我也知道他们在那里。这也让我强制用户退出系统,提供了传递其他系统消息的方法。不错。

于 2009-03-26T14:23:37.747 回答
3

在 Global.asax

protected void Application_Start(object sender, EventArgs e)
        {
            Application["SessionCount"] = 0;
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            Application.Lock();
            Application["SessionCount"] = Convert.ToInt32(Application["SessionCount"]) + 1;
            Application.UnLock();
        }

        protected void Session_End(object sender, EventArgs e)
        {
            Application.Lock();
            Application["SessionCount"] = Convert.ToInt32(Application["SessionCount"]) - 1;
            Application.UnLock();
        }

在你想要的页面上获取 Application["SessionCount"]

于 2016-12-16T20:55:17.133 回答
2

如果使用 SQL Server 进行会话存储(即<sessionState>web.config 中的模式为“SQLServer”),则不能使用依赖Session_Endglobal.asax的解决方案,因为该方法永远不会被调用。

但是,假设SQL 代理正在正确运行DeleteExpiredSessions作业(安装 SQL 状态时它应该是默认的),您可以对 Session Db 运行以下 SQL:

SELECT COUNT(SessionId) FROM ASPStateTempSessions
于 2010-05-27T13:59:48.670 回答
1

我认为我过去使用的是 Global.asax 函数,主要以 Session_Start 和 Session_End 为中心,随着开始增加计数,然后由于会话超时而结束有点棘手。如果您不太关心计数的准确性,那么您可以在这里停下来。

如果不是,那么您可能会结合使用 javascript onUnload 事件和某种 ajax 请求来使会话无效并减去用户。该事件必须查看用户是实际离开该页面还是只是转到站点上的另一个页面。

无论如何,从那里开始。我记得与 ASP 站点有关,因此肯定有一些关于此方法的信息。

于 2009-03-26T15:20:10.827 回答
1

ASP.NET 性能对象中有活动会话的性能监视器统计信息,您可以跟踪所有实例或单个应用程序。您可以通过Admin ToolsPerformance或以编程方式通过WMI访问这些统计信息。

一个非常基本的 PowerShell 脚本,用于获取此类计数器的总数:

(Get-WmiObject Win32_PerfRawData_ASPNET_ASPNETApplications SessionsActive).SessionsActive

过滤器应该能够获取特定站点的统计信息。

于 2009-03-26T15:30:19.427 回答
0

首先将会话超时设置为 1 分钟。

创建一个没有 HTML 内容的简单 heartbeat.aspx 页面,只需以下 javascript 代码:

<html>
  <head>
  <script language="javascript">
  function reloadPage()
  {
    window.navigate("heartbeat.aspx");
  }
  </script>
  </head>
<body onload="window. setTimeout(‘reloadPage()’, 30000)">
</body>
</html>

这将每 30 秒重新请求一次并保持会话处于活动状态。

将 heatbeat.aspx 页面放在一个隐藏的框架中。

要获取用户计数,只需使用 Global.asax 中的 Session_Start 和 Session_End 事件中的静态计数器来获取会话计数。

于 2009-03-26T18:15:18.533 回答
0

如果您使用 InProc 会话状态,您可以在 global.asax 中这样做

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    Application("ActiveSessionCount") = 0
End Sub

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
    Application("ActiveSessionCount") += 1
End Sub

Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
    Application("ActiveSessionCount") -= 1
End Sub

访问 Web 表单上的值同样简单

Dim Count as Integer = Application("ActiveSessionCount")
于 2009-03-26T18:22:18.827 回答
0
public class ActiveUsers
{
    private static List<LastUserActivity> users;
    private static object syncroot = new object();
    private static DateTime lastPruned;

    public static int SessionLength = 20;

    static ActiveUsers()
    {
        users = new List<LastUserActivity>();
        lastPruned = DateTime.UtcNow;
    }

    public void RecordUserActivity(int userId)
    {
        lock (syncroot)
        {
            var user = users.FirstOrDefault(x => x.UserId == userId);
            if (user == null)
            {
                user = new LastUserActivity() { UserId = userId };
                users.Add(user);
            }
            user.UtcTime = DateTime.UtcNow;

            if (lastPruned.AddMinutes(5) < DateTime.UtcNow)
            {
                Prune();
                lastPruned = DateTime.UtcNow;
            }
        }
    }

    private static void Prune()
    {
        users.RemoveAll(x => x.UtcTime.AddMinutes(SessionLength) < DateTime.UtcNow);
    }

    public int GetActiveUsers()
    {
        return users.Count;
    }
}
public class LastUserActivity
{
    public int UserId { get; set; }
    public DateTime UtcTime { get; set; }
}

ActiveUsersglobal.asax(例如,BeginRequest、AcquireRequestState)中添加对方法的调用。

于 2016-11-26T19:41:58.230 回答