ASP.NET中利用Application和Session统计在线人数、历史访问量

转载自:http://www.tuicool.com/articles/qyE3e2a数据库

先来简单说一下ASP.NET中的Application和Session数组

下图是咱们很是熟悉的Web应用程序的结构:浏览器

在这张图中,Web服务器中运行的Web应用程序就是咱们所说的Application,每一个客户端与Web服务器之间创建的链接就能够看作是一个Session。好比如今服务器端运行的是一个论坛系统,那么如今这个正运行在服务器端的论坛系统的软件就能够看作Application,而每一个在线的用户与之创建的链接就至关于一个Session。服务器

那么很容易就会理解,Application是共享的,至关于“全局变量”,Session不是共享的,是属于每一个客户端(浏览器)私有的。测试

因此上图用Application和Session 能够 表示为:ui

Applicationspa

经常使用属性:server

      属性     说明
All 返回所有的Application对象变量到一个对象数组
AllKeys 返回所有的Application对象变量到一个字符串数组
Count 返回Application中对象变量的数量

经常使用方法:对象

  方法  说明
Add 新增一个Application变量值
Clear 清空所有Application变量值
Get 变量名传回的变量值
Set 更新Application变量值
Lock 锁定全部Application的变量值
UnLock 解除锁定Application的变量值

        Sessionblog

经常使用属性:

          属性         说明
Count  获取会话状态集合中Session对象的个数
Contents 获取对当前会话状态对象的引用
Keys 获取存储在会话中的全部值的集合
SessionID 获取用于标识会话的惟一会话ID
TimeOut  获取或设置会话状态提供程序终止会话以前所容许的超时期限
Mode 获取当前会话状态模式

 

经常使用方法:

    方法     说明
Add 新增一个Session对象
Clear 清除会话状态中的全部值
CopyTo 将会话状态值的集合富之岛一维数组中
Remove 删除会话状态集合中的项
RemoveAll 清除全部会话状态的值

ASP.NET中统计在线人数和历史访问人数,还须要四个事件:Application_Start()事件、Application_End()、Session_Start()事件和Session_End()事件。

当程序启动时,会首先在Global.asax.cs文件中触发Application的Application_Start()事件,咱们须要在这个事件中增长两个Application变量值(由于这两个值是Application中的变量值,因此就至关于整个程序的“公共变量”):totalCount(用来表示总的访问量)、onlineCount(用来表示当前在线人数):         

protected void Application_Start()   {    string strConn = "server=192.168.24.123;database=数据库名;uid=sa;pwd=123456;"; //数据库链接字符串    SqlConnection conn = new SqlConnection(strConn); //实例化数据库链接对象    conn.Open(); //打开数据库链接    string cmdText = "select count from Count"; //定义查询字符串    SqlCommand cmd = new SqlCommand(cmdText, conn); //实例化命令对象    int count = (int)cmd.ExecuteScalar(); //取出数据库中历史访问人数    Application["total"] = count; //定义Application变量值total并赋值为历史访问量    Application["onLine"] = 0; //定义Application变量值onLine并赋值为0   }

 

下面就要编写Session_Start()事件代码,当每一个客户端(浏览器)访问服务器时,就会触发Session_Start()事件,这事就要让“公共变量”totalCount和onlineCount都自增1,这时,当有多个客户端同时访问时,就有可能发生错误,因此要Application的Lock()方法先把Application中的变量锁起来(Application执行了Lock()方法以后, 整站中全部关于Application的操做都会被锁定延时执行,包括Application赋值和Application读取),只让一个客户端进行这两个变量的自增,以后再进行解锁,供其余客户端进行操做:      

protected void Session_Start()   {    Application.Lock(); //锁定Application    Application["total"] = (int)Application["total"] + 1; //总访问量加1    Application["onLine"] = (int)Application["onLine"] + 1; //在线人数加1    Application.UnLock(); //解除锁定   }

如今在线人数和历史访问数量都统计出来了,须要显示的时候直接调用Application["变量值"]就能够,好比要在名为Label的控件上显示在线人数,只需Label.Text=Application["onLine"].ToString()就OK了!须要 注意 的是,Application和Session中存储的变量值都是object类型的,给他们赋值的时候能够直接赋值,可是取出的时候就须要考虑类型了。

当一个客户端(浏览器)与服务器断开链接(即此客户端与服务器的会话关闭)时,会触发Session_End()事件,这时历史访问数量不改变,在线人数须要减1:

protected void Session_End() { Application.Lock(); //锁定Application Application["onLine"] = (int)Application["onLine"] - 1; //总访问数量不变,在线人数减1 Application.UnLock(); //解除锁定 }

 

为了方便测试,上面的例子能够经过在一台电脑上开启多个浏览器,也就至关于与服务器创建了多个Session,也许您测试的时候会发现一个问题,假如如今在线人数是10,您关闭了某个浏览器时,测试当前的在线人数即Application["onLine"]的值仍是10 ,并无执行“减1”操做。这是由于Session的TimeOut值默认是20分钟,也就是说,默认状况下,关闭了浏览器并不表明这个浏览器和服务器之间的链接已经断开,而要等待20分钟以后才会断开链接。(为了测试效果,您能够将TimeOut的值设置小一点)

最后,假如服务器要关闭,就要把目前Application中存储的历史访问总数从新更新到数据库中,须要在Application_End()事件中进行:

protected void Application_End()   {    string strConn = "server=192.168.24.123;database=数据库名;uid=sa;pwd=123456;"; //定义数据库链接字符串    SqlConnection conn = new SqlConnection(strConn); //实例化数据库链接对象    conn.Open(); //打开数据库链接    string cmdText = "update Count set count=@count"; //定义执行命令    SqlCommand cmd = new SqlCommand(cmdText, conn); //实例化命令对象    cmd.Parameters.Add(new SqlParameter("@count", Application["total"])); //为参数@count赋值为如今的总访问量    cmd.ExecuteNonQuery(); //执行命令    conn.Close(); //关闭数据库   }

一般在整个过程当中,大多数人对Application_End()这个事件的疑问是最大的,由于若是您只是在VisualStudio上作的测试的话,关闭系统时,没有触发Application_End()事件,新的数据也就没有被写入到数据库中。那么Application_End()究竟在何时才会被触发呢 ?

想弄明白这个问题,须要将程序发布,这里以IIS为例,用IIS发布了程序以后运行,当想要触发Application_End()事件把最新的历史访问量写入到 数据库中时,须要在IIS中关闭此程序的运行,以下图:

注意 :只是在服务器上中止该程序的运行才会触发Application_End()事件,重启和断电等状况并不能触发。

 

虽然统计在线人数和历史访问量是个并不起眼的小功能,可是经过捋一遍,细细地总结了一下,又学到了好多东西,脑子里的知识网又增大了一点点。。。。

相关文章
相关标签/搜索