如何在ASP.NET中获得准确的访问者总数

我想知道我网站上的在线访客数量。 我做了我的研究,找到了两个解决方案。

资料来源:代码项目
ASP.NET中的在线活动用户计数器

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

来源:Stack Overflow Q / A.
计算访客数量这个与前一个完全相同。

来源:ASP.Net论坛如何使用C#查看“谁在线”

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

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中。

你可以做什么:

  • 在应用程序范围中保存Dictionary 。 此存储的session-id(字符串键)与最新访问时间(DateTime值)
  • 对于具有有效会话的每个请求,在字典中查找会话条目并更新它的最新访问时间(如果未找到则添加新条目)
  • 当您想获得在线用户的数量时,首先遍历字典中的所有条目并删除会话超时已经过去的项目。 剩余计数是在线用户数。

一个问题(至少):如果一个用户同时使用两个浏览器,他有两个会话打开并被计为两倍。 如果用户总是登录,也许您可​​以依靠login-id而不是session-id。

我想提出另一个完全不同的东西:尝试使用Google Analytic。 这些人添加了测试function,允许现在跟踪在线统计。

编辑:你没有得到我。 我提到的不是标准的Google Analyticfunction。 我提到了新function – 实时。 查看下一篇文章了解详细信息 – 您网站上现在发生了什么? 或观看此video – Google Analytics实时测试版

就像Hans提到的那样,你可能不得不将会话状态切换到StateServerSQLServer ,但这不是一段代码可以做的事情。 有关codeproject的非常好的可靠和详细的文章正确地处理了这个问题。

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

Global.asax中

 void Session_Start(object sender, EventArgs e) { System.Collections.Generic.Dictionary Visitors = new System.Collections.Generic.Dictionary(); Visitors.Add(Session.SessionID, DateTime.Now); HttpContext.Current.Application.Lock(); Application["Visitors"] = Visitors; HttpContext.Current.Application.UnLock(); } 

HttpHandleder.cs

 private static void UpdateVisitors() { System.Collections.Generic.Dictionary Visitors = (System.Collections.Generic.Dictionary)HttpContext.Current.Application["Visitors"]; Visitors[HttpContext.Current.Session.SessionID] = DateTime.Now; } 

AnyPage.aspx.cs(你想获得在线总用户数)

  protected int GetCurrentOnlineUsers() { int total = 0; Dictionary Visitors = (Dictionary)Application["Visitors"]; foreach (KeyValuePair pair in Visitors) { TimeSpan Remaining = DateTime.Now - pair.Value; int remainingMinutes = Convert.ToInt32(Remaining.TotalMinutes); if (remainingMinutes < 21) //Only count the visitors who have been active less than 20 minutes ago. total++; } return total; } 

Hans的解决方案非常棒,并且正是我想要的,但我刚刚在MSDN上找到了这篇文章,这似乎是为此目的的最佳实践。

参考: http : //msdn.microsoft.com/en-AU/library/system.web.httprequest.anonymousid.aspx

Global.asax中

 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#" %>     AnonymousID Example   
Number of users:
Current user:

为什么不检查用户IP以获得唯一访问。 将它们添加到哈希集中,这样您就可以使用位置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)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)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 {} }