跟踪每个请求的访问者信息



使用Asp.net webforms,我想跟踪访问者信息,就像谷歌分析一样。当然,我可以使用谷歌分析来达到这个目的,但我想知道如何在Asp.net 3.5和SQL Server 2008中实现同样的事情。

我想存储IP,国家,URL访问者的推荐人,除回发以外的每个页面请求的分辨率。.

主要关注的是我想以一种不应该阻塞当前请求的方式来做。

。e一般情况下,当我们将数据保存到db中时,当前请求停止在特定的SP调用语句上,并在完成执行SP或tsql语句时继续前进。我想遵循"插入并忘记"的方法。当我将参数传递给特定的事件或函数时,它应该在后台插入。

我找到了以下替代方法:
1. PageAsynchTask
2. BeginExecuteNonQuery
3.Jquery Post方法和Webservice(但我对此没有信心,并想知道我应该如何去做)

我希望我恰当地提到了我的问题。

谁能告诉我哪个方法更好?也让我知道,如果你有任何其他的想法或更好的方法比列出的一个。非常感谢你的帮助。

服务器端任何后台线程的问题是每个请求都将占用两个线程。一个是为ASP服务。NET请求和一个用于记录您想要记录的内容。因此,由于ASP的耗尽,您最终会遇到可伸缩性问题。净线程。在数据库中记录每一个请求是一个大禁忌。

最好是使用一些高性能的日志库写入日志文件。日志库针对多线程日志进行了高度优化。它们不会对每个调用都产生I/O调用。日志存储在内存缓冲区中,并定期刷新。您应该使用EntLib或Log4net进行日志记录。

你可以使用一个HttpModule来拦截每个GET, POST,然后在HttpModule中你可以检查请求是否正确。Url是否为aspx。然后你可以阅读请求。Headers["__ASYNCPOST"],看看它是否为"true",这意味着它是一个UpdatePanel异步更新。如果所有这些条件都为真,则只需将请求记录到存储

的日志文件中。

客户端IP地址:

HttpContext.Current.Request.UserHostAddress; 
or 
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

要获取机器的IP地址,而不是代理,使用以下代码

HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

然而你不能得到这个国家。您必须在日志文件中记录IP,然后使用一些控制台应用程序或作业来处理日志文件,这些应用程序或作业将解析IP的国家。您需要获得一些IP->国家数据库来完成这项工作。我以前用过http://www.maxmind.com/app/geoip_country。

对于屏幕大小,您将不得不依赖一些javascript。在每个页面上使用javascript查找客户端的屏幕大小并存储在cookie中。

var screenW = 640, screenH = 480;
if (parseInt(navigator.appVersion)>3) {
 screenW = screen.width;
 screenH = screen.height;
}
else if (navigator.appName == "Netscape" 
    && parseInt(navigator.appVersion)==3
    && navigator.javaEnabled()
   ) 
{
 var jToolkit = java.awt.Toolkit.getDefaultToolkit();
 var jScreenSize = jToolkit.getScreenSize();
 screenW = jScreenSize.width;
 screenH = jScreenSize.height;
}

一旦你将它存储在一个cookie中(我没有显示代码),你可以通过使用Request从HttpModule读取屏幕尺寸。cookie,然后将其记录在日志文件中。

所以,这给你的解决方案,记录IP,屏幕大小,从IP查找国家,并从日志中过滤UpdatePanel异步回发。

这就给你一个完整的解决问题的办法了吗?

说到服务器端,如果你在IIS上运行,你不需要绝对的实时信息,我建议你使用IIS日志。

没有比这更快的了,因为它从IIS 1.0开始就进行了性能优化

你可以在这些日志中附加你自己的信息(HttpRequest.AppendToLog),他们有一个标准的格式,有一个API,如果你想用它做自定义的事情(但你仍然可以使用文本解析器,如果你喜欢),有很多免费的工具,例如微软日志解析器可以在SQL数据库中传输数据(等)。

第一种方法看起来不错。(我推荐这么做。)但它有两个缺点:

  1. 请求仍然会阻塞,直到任务完成(或超时终止)。
  2. 你必须在每个页面注册你的任务。

第二种方法看起来不方便,可能会导致错误。(您必须注意页面呈现速度快于查询处理速度的情况。我不确定如果您的查询不完成时,您的页面对象被销毁和GC继续finalize()狂欢会发生什么…但我想没什么好东西。你可以通过等待IAsyncResult来避免它。完成后渲染,但这是不方便的)

第三种方法显然是错误的。在处理要记录日志的请求时,应该在服务器端上启动日志记录。但是您仍然可以从服务器端调用web服务。(或者win service).

就我个人而言,我想在BeginRequest中实现日志记录以避免代码重复,但你需要IsPostback…不过,也许还有一个变通办法。

你好,您可以触发异步请求而不等待响应。这里我有一些实现的代码。

你需要创建一个web服务来做你的数据库操作,或者你可以用它来处理整个事件。

从服务器端,你必须异步调用web服务,像这样

声明私有委托

private delegate void ReEntryDelegate(long CaseID, string MessageText);

现在该方法将包含像这样的web服务调用

WebServiceTest.Notification service = new WebServiceTest.Notification();
IAsyncResult handle;
ReEntryDelegate objAscReEntry = new ReEntryDelegate(service.ReEntryNotifications);
handle = objAscReEntry.BeginInvoke(CaseID, MessageText, null, null);
break;

变量值将通过这里的方法传递(CaseID,MessageText)

希望你明白了

All the Best

最新更新