如何在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提到的那样,你可能不得不将会话状态切换到StateServer
或SQLServer
,但这不是一段代码可以做的事情。 有关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
为什么不检查用户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 {} }