网站统计模块综述(Session,Application的讨论)
windfly. http://windfly.blog.ccidnet.com/

在ASP.NET梦工厂群中,有朋友寻网站当前在线人数和所有访问次数的代码,因为正好看到书上有这个例子就应了下来,结果却小弄了好一阵才搞定,不过还真有些需要注意的问题,在此总结,希望和大家共同交流。
    原本在VS2003中默认已经建立的web.config文件和Global.asax,在05下都需要手动添加了,下面就是添加 Global.asax 的界面:手动添加Global.asax

 

 

 

 

 

 

 

 

 

 

下面是默认生成的Global.asax的代码,和03也有了些许不同,函数的声明也有了小变化。
<%@ Application Language="C#" %>

    这里需要注意的是 Session_End 事件,只有 InProc 模式支持该事件,也就是说,只有将会话数据存储在 ASP.NET 辅助进程中时才支持该事件。它标志着会话的结束,并用于执行终止该会话所需的所有清除代码。对于要引发的 Session_End 事件来说,必须首先存在会话状态,这意味着必须在该会话状态中存储一些数据,并且必须至少完成一个请求。如果会话状态属性 Mode 为 StateServer 或 SQLServer,则忽略 Global.asax 文件中的 Session_End 事件。如果会话状态属性 Mode 设置为 Custom,则由自定义会话状态存储提供程序决定是否支持 Session_End 事件。
     会话状态的配置是通过设置Web.config文件的节来实现的。下面介绍一下进程内模式的配置方法,它也是默认的会话状态模式。若要使用进程内模式,请将 元素的 mode 属性设置为 Inproc。
下面显示了进程内模式的一个配置设置示例。

   
                              cookieless="false"
                      timeout="20"/>
       

   

    下面是我的Global.asax的完整代码,其中在线统计的部分借鉴了 MSDN 中的方法,而没有使用 Session 对象,所有访问次数的统计是采用了读写文件的方式,需要在应用程序中加一个 Counter.txt 文本文件。
<%@ Application Language="C#" %>
<%@ Import Namespace="System.IO" %>


下面是我的测试页面 WebCount.aspx,简单地在页面上加两个lable显示人数即可:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class WebCount : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (Application["UsersOnline"] != null)
            {
                //获取当前在线人数
                currentUserNum.Text = Application["UsersOnline"].ToString();
            }
            if (Application["TotalCount"] != null)
            {
                //获取网站总访问人数
                totalUserNum.Text = Application["TotalCount"].ToString();
            }
        }
    }
}

    具体的有关会话管理的知识可以查看帮助,这里仅就一个问题和大家讨论,路过者有熟悉的请留言或加QQ:65127444
程序里之所以都使用了 Application ,而没有使用 Session,是因为我使用 一书中第10章的模块 时调试未成功 :(
    下面的代码是这本书中使用 Session 的,可我经过调试,即使多用户同时访问,也还是显示当前在线为1。
它的实现方式是:将以下代码写在 Session_Start 中,然后在 Session_End 中再减1。
   if(Session["CurrentCount"] != null)
   {
    Session["CurrentCount"] = Int32.Parse(Session["CurrentCount"].ToString()) + 1;
   }
   else
   {
    Session["CurrentCount"] = 1;
   }
    然后将 Page_Load 中显示当前人数的Application["UsersOnline"].ToString() 改为 Session["CurrentCount"].ToString(),不管几个用户同时访问,每个人的浏览器显示的当前人数均为 1。
    呵呵,总结到这里,忽然醒悟了,看来总结也是好处不少啊,呵呵,先说说我写到这里时的理解吧:对象 Session 仅被单个用户所共享,所以,每个用户登录时,Session["CurrentCount"] 都为空,所以,都被赋值为1了,似乎这也充分说明了一些写计算机书籍的人的不负责任,呵呵,随便凑合能看就出版了,代码正确率很低啊!至少,我测试得到的不是想要的结果,也许,我个人的理解有偏差?高手路过的请指点一下了!
    当然,利用读写文件的方式,还可以统计最大在线人数。就是将Application["UsersOnline"]的值和用于保存最大在线人数的文件(如:maxcount.txt)中的值比较,大于则重写,小于则不改变即可。有兴趣的可以自己实现一下,呵呵,好累!
    继续努力了一下,呵呵,最大在线人数的也有了:
        //最大在线人数
        DataSet objDataSet = new DataSet();
        objDataSet.ReadXml(Server.MapPath("count.xml"));
        int maxCount = Convert.ToInt32(objDataSet.Tables["MyCount"].Rows[0]["MaxCount"]);
        Application["MaxCount"] = maxCount;
        if (maxCount < (int)Application["UsersOnline"])    //如果MaxCount标签里面的值小于当前在线人数的值,就存入
            objDataSet.Tables["MyCount"].Rows[0]["MaxCount"] = (int)Application["UsersOnline"];
            objDataSet.WriteXml(Server.MapPath("count.xml"));
附:count.xml:


  0

CIO之家 www.ciozj.com 公众号:imciow
关联的文档
也许您喜欢