ZT:ASP.NET 在线统计的研究 .

其实刚进公司的时候就发现公司的OA系统上有在线统计功能,但那时候没有心情来研究这个东西,这不最近闲的慌,就研究了下它.

这一研究,还真有满多学问在里面的.对于我个人的理解,在线统计的实时性不高,即一般不可能做到有人离开马上就改变在线人数的. 

而离开又分两种情况:第一种是用户点击退出离开的,第二种是用户直接关闭浏览器的(即非正常离开的).

第一种情况实时性要高点,好处理,毕竟是点击了退出按钮触发了事件的.而对于第二种情况的话,根本不存在实时性可言,而只能尽快的发现这个用户已经离开.

首先新建一个Global.asax文件.在这个文件里面的Application_start中写:

Hashtable ht = new Hashtable();
Application[
"UserName"= ht;

Hashtable是一个键/值对,键用用户的登录名,值用用户活动的当前时间.(后面用到的Hashtable都是如此)

在Session_end中写:

       Hashtable ht = (Hashtable)Application["UserName"];
        
foreach (DictionaryEntry item in ht)
        
{
            
if (DateTime.Parse(item.Value.ToString()).AddSeconds(20.0< DateTime.Now)
            
{
                ht.Remove(item.Key);
            }

        }

这里要补充说明下,有两种情况会触发Session_end事件.第一种是Session超时,第二种就是调用Session.Abandon()的时候.看到这里读者应该能猜到怎么处理用户非法离开的情况了把?没错,用户非法离开,那只能等Session超时了,然后就会触发Session_end事件,将Hashtable中该用户名删除.这里我们判断用户是不是非法离开的方法是,用用户最后一次活动时间加上20秒和当前时间进行比较,如果小的话,就表示用户已经离开了本站了.这里只是举例子,一般都不只20秒的.

在登录按钮中写:

protected void btnLogin_Click(object sender, EventArgs e)
    
{
        SqlConnection conn 
= new SqlConnection("server=localhost;database=test;uid=sa;pwd=");
        SqlCommand cmd 
= conn.CreateCommand();
        conn.Open();
        cmd.CommandText 
= "select * from UserInfo where username='" + txtUserName.Text + "' and userpwd='" + txtPwd.Text + "'";
        SqlDataReader sdr 
= cmd.ExecuteReader();
        
if (sdr.Read())
        
{
            Session[
"UserName"= txtUserName.Text;
            
string str=DateTime.Now.ToString();
            Session[
"Key"= str;
            Hashtable ht 
= (Hashtable)Application["UserName"];
            ht.Add(txtUserName.Text,str);
            

            Response.Redirect("index.aspx");
        }

        
else
        
{
            Response.Write(
"<script>alert('用户名或密码错误');</script>");
        }

    }
index.aspx页面中有一个iframe和一个JS函数还有退出按钮需要注意.iframe的src是main.aspx,而main.aspx中的内容是在线统计信息.JS函数是用来不断的刷新这个IFRAME.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
    
<script>
    function getUser()
    
{
        ifr.document.location.href
=ifr.document.location.href;
        window.setTimeout(
'getUser()',30000);
    }

    
</script>
</head>
<body onload="getUser()">
    
<form id="form1" runat="server">
    
<div>
    
<iframe id="ifr" name="ifr" src="main.aspx"></iframe>
        
<asp:Button ID="btnCancle" runat="server" OnClick="btnCancle_Click" Text="退出" /></div>
    
</form>
</body>
</html>
index.aspx.cs中的退出按钮事件委托:
 protected void btnCancle_Click(object sender, EventArgs e)
    
{
        Hashtable ht 
= (Hashtable)Application["UserName"];
        
        ht.Remove(Session[
"UserName"].ToString());
        Session.Clear();
        Session.Abandon();
        Response.Write(
"<script>window.opener=null;window.close();</script>");
    }
main.aspx.cs在page_load中写:
if(!IsPostBack)
        
{
            Session.Timeout 
+= 1;
            Response.Write(Session.Timeout);
            Response.Write(Session[
"UserName"].ToString());
            
if (Session["Key"].ToString() == DateTime.Now.ToString())
            
{
                Response.Write(
"YES");
            }

            
else
            
{
                Response.Write(
"NO");
            }

            Hashtable ht 
= (Hashtable)Application["UserName"];

            ht[Session[
"UserName"].ToString()] = DateTime.Now.ToString();
            
string str = "UserList:";
            
string str1 = "";
            
foreach (DictionaryEntry item in ht)
            
{
                str 
+= "|" + item.Value.ToString();
                str1 
+= item.Key.ToString() + ",";
            }

            Response.Write(str);
            
            Response.Write(str1);
        }

每被刷新一次,Session的过期时间就会加1分钟,这样做是为了区别当Session过期和用户点击退出同时成立的情况.

只有当用户没有离开该页面,该页面才会被刷新,被刷新了Session过期时间就加1分钟.而用户直接关闭浏览器了该页面就不会被刷新,Session就会更早的过期.

posted @ 2011-07-23 05:16  青衫  阅读(307)  评论(0编辑  收藏  举报