ZT:ASP.NET 在线统计的研究 .
其实刚进公司的时候就发现公司的OA系统上有在线统计功能,但那时候没有心情来研究这个东西,这不最近闲的慌,就研究了下它.
这一研究,还真有满多学问在里面的.对于我个人的理解,在线统计的实时性不高,即一般不可能做到有人离开马上就改变在线人数的.
而离开又分两种情况:第一种是用户点击退出离开的,第二种是用户直接关闭浏览器的(即非正常离开的).
第一种情况实时性要高点,好处理,毕竟是点击了退出按钮触发了事件的.而对于第二种情况的话,根本不存在实时性可言,而只能尽快的发现这个用户已经离开.
首先新建一个Global.asax文件.在这个文件里面的Application_start中写:
Application["UserName"] = ht;
Hashtable是一个键/值对,键用用户的登录名,值用用户活动的当前时间.(后面用到的Hashtable都是如此)
在Session_end中写:
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秒的.
在登录按钮中写:
{
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>");
}
}
<!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>
{
Hashtable ht = (Hashtable)Application["UserName"];
ht.Remove(Session["UserName"].ToString());
Session.Clear();
Session.Abandon();
Response.Write("<script>window.opener=null;window.close();</script>");
}
{
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就会更早的过期.