C# 如何在ASP.NET中获得准确的总访客数

C# 如何在ASP.NET中获得准确的总访客数,c#,asp.net,c#-2.0,C#,Asp.net,C# 2.0,我想知道我网站上的在线访问者数量。我做了研究,发现了两个解决方案 来源:代码项目 它易于设置和使用,但也增加了每个Ajax请求/响应的用户数。仅我的主页就有12个Ajax请求(一个页面有8个请求,另一个页面有4个请求)。这大大增加了用户数量 来源:堆栈溢出Q/A 这个和前一个完全一样 资料来源:ASP.Net论坛 这个看起来比前两个好。下面是此解决方案的详细代码 void Application_Start(object sender, EventArgs e) {

我想知道我网站上的在线访问者数量。我做了研究,发现了两个解决方案

来源:代码项目

它易于设置和使用,但也增加了每个Ajax请求/响应的用户数。仅我的主页就有12个Ajax请求(一个页面有8个请求,另一个页面有4个请求)。这大大增加了用户数量

来源:堆栈溢出Q/A
这个和前一个完全一样

资料来源:ASP.Net论坛

这个看起来比前两个好。下面是此解决方案的详细代码

void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        HttpContext.Current.Application["visitors_online"] = 0;
    }

void Session_Start(object sender, EventArgs e) 
    {
        Session.Timeout = 20; //'20 minute timeout
        HttpContext.Current.Application.Lock();
        Application["visitors_online"] = Convert.ToInt64(HttpContext.Current.Application["visitors_online"]) + 1;
        HttpContext.Current.Application.UnLock();
    }

void Session_End(object sender, EventArgs e) 
    {
        HttpContext.Current.Application.Lock();
        Application["visitors_online"] = Convert.ToInt64(HttpContext.Current.Application["visitors_online"]) - 1;
        HttpContext.Current.Application.UnLock();
    }
它似乎可以忽略增加每个Ajax响应的计数,但它仍然会增加每个页面刷新或页面请求的计数


有什么方法可以计算ASP.Net中在线访问者的准确数量吗?

你永远无法得到一个完全准确的数字:无法(可靠地)检测到用户“已导航到另一个站点”(并离开了你的站点)或该用户“关闭了浏览器”

Session_Start/Session_End方式存在一个问题,即Session_End仅为“InProc”会话调用,而不是在会话存储在StateServer或SqlServer中时调用

您可以做什么:

  • 在应用范围内持有
    词典
    。此存储的会话id(字符串键)与最新访问时间(DateTime值)相对应
  • 对于每个具有有效会话的请求,请在字典中查找会话条目并更新其最新访问时间(如果未找到,请添加新条目)
  • 当您想要获取联机用户的数量时,首先循环字典中的所有条目,并删除会话超时已过的项目。剩余的计数是联机用户数

一个问题(至少):如果一个用户同时使用两个浏览器,他会打开两个会话,并且会被加倍计算。如果用户总是登录,也许您可以使用登录id而不是会话id。

正如Hans提到的,您可能需要将会话状态切换到
StateServer
SQLServer
,但这不是一段代码可以做到的。有一个非常好的、可靠的、正确处理这个问题的方法。

这是我根据Hans Kesting的建议实现的源代码

Global.asax

void Session_Start(object sender, EventArgs e) 
    {
        System.Collections.Generic.Dictionary<string, DateTime> Visitors =
                            new System.Collections.Generic.Dictionary<string, DateTime>();
        Visitors.Add(Session.SessionID, DateTime.Now);        
        HttpContext.Current.Application.Lock();
        Application["Visitors"] = Visitors;
        HttpContext.Current.Application.UnLock();
    }
void Application_Start(Object sender, EventArgs e)
    {
        // Initialize user count property
        Application["UserCount"] = 0;
    }

public void AnonymousIdentification_Creating(Object sender, AnonymousIdentificationEventArgs e)
    {
    // Change the anonymous id
    e.AnonymousID = "mysite.com_Anonymous_User_" + DateTime.Now.Ticks;

    // Increment count of unique anonymous users
    Application["UserCount"] = Int32.Parse(Application["UserCount"].ToString()) + 1;
}
void会话\u启动(对象发送方,事件参数e)
{
System.Collections.Generic.Dictionary访问者=
新的System.Collections.Generic.Dictionary();
添加(Session.SessionID,DateTime.Now);
HttpContext.Current.Application.Lock();
申请[“访客”]=访客;
HttpContext.Current.Application.UnLock();
}
HttpHandleder.cs

private static void UpdateVisitors()
    {
        System.Collections.Generic.Dictionary<string, DateTime> Visitors = (System.Collections.Generic.Dictionary<string, DateTime>)HttpContext.Current.Application["Visitors"];
        Visitors[HttpContext.Current.Session.SessionID] = DateTime.Now;
    }
private static void UpdateVisitors()
{
System.Collections.Generic.Dictionary访问者=(System.Collections.Generic.Dictionary)HttpContext.Current.Application[“访问者];
访问者[HttpContext.Current.Session.SessionID]=DateTime.Now;
}
AnyPage.aspx.cs(您希望从中获取在线用户总数)

protected int GetCurrentOnlineUsers()
{
int-total=0;
字典访问者=(字典)应用程序[“访问者];
foreach(访客中的KeyValuePair对)
{
剩余时间跨度=DateTime.Now-pair.Value;
int remainingMinutes=Convert.ToInt32(剩余的.TotalMinutes);
if(remainingMinutes<21)//只统计20分钟前活跃的访客。
总计++;
}
返回总数;
}

我想提出另一个完全不同的建议:尝试使用Google Analytic。这些家伙添加了测试版功能,现在可以跟踪在线统计数据


编辑:你不明白我的意思。我提到的不是标准的谷歌分析功能。我提到了新功能——实时。查看下一篇文章以了解详细信息,或者观看此视频-

Hans的解决方案非常棒,完全符合我的要求,但我最近在MSDN上发现了这篇文章,这似乎是实现此目的的最佳实践

参考:

Global.asax

void Session_Start(object sender, EventArgs e) 
    {
        System.Collections.Generic.Dictionary<string, DateTime> Visitors =
                            new System.Collections.Generic.Dictionary<string, DateTime>();
        Visitors.Add(Session.SessionID, DateTime.Now);        
        HttpContext.Current.Application.Lock();
        Application["Visitors"] = Visitors;
        HttpContext.Current.Application.UnLock();
    }
void Application_Start(Object sender, EventArgs e)
    {
        // Initialize user count property
        Application["UserCount"] = 0;
    }

public void AnonymousIdentification_Creating(Object sender, AnonymousIdentificationEventArgs e)
    {
    // Change the anonymous id
    e.AnonymousID = "mysite.com_Anonymous_User_" + DateTime.Now.Ticks;

    // Increment count of unique anonymous users
    Application["UserCount"] = Int32.Parse(Application["UserCount"].ToString()) + 1;
}
.ASPX文件

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  void Page_Load(object sender, EventArgs e)
    {
      if (Application["UserCount"] != null)
      {
          lblUserCount.Text = Application["UserCount"].ToString();
          lblCurrentUser.Text = Request.AnonymousID;
      }
  }    
</script>


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>AnonymousID Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Number of users: 
        <asp:Label ID="lblUserCount" Runat="server"></asp:Label><br />
    Current user:
        <asp:Label ID="lblCurrentUser" Runat="server"></asp:Label><br />
    </div>
    </form>
</body>
</html>

无效页面加载(对象发送方,事件参数e)
{
if(应用程序[“用户计数”]!=null)
{
lblUserCount.Text=应用程序[“UserCount”].ToString();
lblCurrentUser.Text=Request.AnonymousID;
}
}    
匿名ID示例
用户数:

当前用户:

为什么不检查用户IP以获得唯一访问。将它们添加到哈希集中,这样您就可以使用location API制作热图:

 // count users online on all desktopsites
        void Session_Start(object sender, EventArgs e)
        {
            try
            {
                // lock application object
                Application.Lock();

                // get hashset containing all online ip adresses
                var ips = (HashSet<string>)Application["visitors_online_list_ip"];

                // get user ip
                var ip = HttpContext.Current.Request.UserHostAddress;

                // add ip to hashset
                ips.Add(ip);

                // store ip in session to delete when session ends
                Session["ip"] = ip;

                // save hashset
                Application["visitors_online_list_ip"] = ips;

                // unlock application object 
                Application.UnLock();
            }
            catch {}
        }

        void Session_End(object sender, EventArgs e)
        {
            try
            {
                // lock application object
                Application.Lock();

                // get hashset containing all online ip adresses
                var ips = (HashSet<string>)Application["visitors_online_list_ip"];

                // get user ip from Session because httpcontext doesn't exist
                var ip = Session["ip"].ToString(); ;

                // remove ip from hashset
                ips.Remove(ip);

                // save hashset
                Application["visitors_online_list_ip"] = ips;

                // unlock application object 
                Application.UnLock();
            }
            catch {}
        }
//统计所有桌面站点上的在线用户数
无效会话\u启动(对象发送方,事件参数e)
{
尝试
{
//锁定应用程序对象
Application.Lock();
//获取包含所有联机ip地址的哈希集
var ips=(HashSet)应用程序[“访问者在线列表ip”];
//获取用户ip
var ip=HttpContext.Current.Request.UserHostAddress;
//将ip添加到哈希集
添加(ip);
//在会话结束时要删除的会话中存储ip
会话[“ip”]=ip;
//保存哈希集
应用程序[“访问者在线列表ip”]=ip;
//解锁应用程序对象
Application.UnLock();
}
捕获{}
}
无效会话\u结束(对象发送方,事件参数e)
{
尝试
{
//锁定应用程序对象
Application.Lock();
//获取包含所有联机ip地址的哈希集
变量ips=