对于做B/S开发的人来说,统计在线的人数是个很重要的工作,一般的统计方法是利用Application保存在线人数。我今天要讲的也是用这个方法,但是,在这个方法上增加一点内容,就是,当用户直接关闭IE后,也要立刻将在线人数减少,而一般的方法是要等待Session过期后才能统计。好了,开始了。
1、首先,配置web.config
将Session的状态配置成如下,为什么我就不说了。
<
sessionState mode
=
"
InProc
"
></
sessionState
>
2、Global.asax的各个方法
<%
@ Application Language
=
"
C#
"
%>
< script runat = " server " >
void Application_Start( object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
Application.Add("OAS_Line_Counts", 0);
}
void Application_End( object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
Application.RemoveAll();
}
void Application_Error( object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
}
void Session_Start( object sender, EventArgs e)
{
// 在新会话启动时运行的代码
Session.Timeout = 30;
}
void Session_End( object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
Application.Lock();
if (Application["OAS_Line_Counts"] != null)
{
Application["OAS_Line_Counts"] = Int32.Parse(Application["OAS_Line_Counts"].ToString()) - 1;
if (Int32.Parse(Application["OAS_Line_Counts"].ToString()) < 0)
Application["OAS_Line_Counts"] = 0;
}
Application.UnLock();
}
</ script >
< script runat = " server " >
void Application_Start( object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
Application.Add("OAS_Line_Counts", 0);
}
void Application_End( object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
Application.RemoveAll();
}
void Application_Error( object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
}
void Session_Start( object sender, EventArgs e)
{
// 在新会话启动时运行的代码
Session.Timeout = 30;
}
void Session_End( object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
Application.Lock();
if (Application["OAS_Line_Counts"] != null)
{
Application["OAS_Line_Counts"] = Int32.Parse(Application["OAS_Line_Counts"].ToString()) - 1;
if (Int32.Parse(Application["OAS_Line_Counts"].ToString()) < 0)
Application["OAS_Line_Counts"] = 0;
}
Application.UnLock();
}
</ script >
3、登陆成功后的人数加一
Application.Lock();
if (Application[ " OAS_Line_Counts " ] != null )
{
Application["OAS_Line_Counts"] = Int32.Parse(Application["OAS_Line_Counts"].ToString()) + 1;
}
else
{
Application["OAS_Line_Counts"] = 1;
}
Application.UnLock();
4、退出时减一
if (Application[ " OAS_Line_Counts " ] != null )
{
Application["OAS_Line_Counts"] = Int32.Parse(Application["OAS_Line_Counts"].ToString()) + 1;
}
else
{
Application["OAS_Line_Counts"] = 1;
}
Application.UnLock();
Session.RemoveAll();
Session.Abandon(); // 取消会话状态就会触发Session_End的事件
5、当关闭窗口时的统计(关键的地方)
Session.Abandon(); // 取消会话状态就会触发Session_End的事件
如果页面是用框架结构做的,则里面不能用.net的控件,而且没有body,因此,我们只能调用其他的页面来实现。
我的方法如下:
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
function PageClose()
{
//这样写,主要是防止刷新也触发该事件
if(event.clientX>document.body.clientWidth-30 && event.clientY<0 || event.altKey) //event.altKey表示按下了Alt按纽
{
//alert("X:"+event.clientX+" Y:"+event.clientY+" "+document.body.clientWidth);
window.location .href="PageCloseCount.aspx";
widnow.close();
}
}
</ script >
</ head >
< frameset onbeforeunload = " PageClose() " rows = " 88,* " cols = " * " framespacing = " 0 " frameborder = " no " border = " 0 " bordercolor = " #0099FF " >
< frame src = " top.aspx " name = " topFrame " scrolling = " NO " noresize >
< frameset rows = " * " cols = " 148,* " framespacing = " 0 " frameborder = " no " border = " 0 " bordercolor = " #33CCFF " >
< frame src = " left.aspx " name = " leftFrame " scrolling = " yes " noresize >
< frame src = " desktop.aspx " name = " mainFrame " scrolling = " yes " >
</ frameset >
</ frameset >
< noframes >< body >
</ body ></ noframes >
PageCloseCount里调用的方法
function PageClose()
{
//这样写,主要是防止刷新也触发该事件
if(event.clientX>document.body.clientWidth-30 && event.clientY<0 || event.altKey) //event.altKey表示按下了Alt按纽
{
//alert("X:"+event.clientX+" Y:"+event.clientY+" "+document.body.clientWidth);
window.location .href="PageCloseCount.aspx";
widnow.close();
}
}
</ script >
</ head >
< frameset onbeforeunload = " PageClose() " rows = " 88,* " cols = " * " framespacing = " 0 " frameborder = " no " border = " 0 " bordercolor = " #0099FF " >
< frame src = " top.aspx " name = " topFrame " scrolling = " NO " noresize >
< frameset rows = " * " cols = " 148,* " framespacing = " 0 " frameborder = " no " border = " 0 " bordercolor = " #33CCFF " >
< frame src = " left.aspx " name = " leftFrame " scrolling = " yes " noresize >
< frame src = " desktop.aspx " name = " mainFrame " scrolling = " yes " >
</ frameset >
</ frameset >
< noframes >< body >
</ body ></ noframes >
public
void
PageClose()
{
System.Web.HttpContext.Current.Session.RemoveAll();
System.Web.HttpContext.Current.Session.Abandon();
}
{
System.Web.HttpContext.Current.Session.RemoveAll();
System.Web.HttpContext.Current.Session.Abandon();
}
如果不是用框架做的就要简单些了,可以不需要调用其他的页面来执行方法,用他自己就可以了。
部分代码:
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
function PageClose()
{
if(event.clientX>document.body.clientWidth -30 && event.clientY<0 || event.altKey) //event.altKey表示按下了Alt按纽
{
document.all('ButtonPageClose').click();
document.all('ButtonPageClose').focus();
}
}
</ script >
</ head >
< body onbeforeunload = " PageClose() " >
function PageClose()
{
if(event.clientX>document.body.clientWidth -30 && event.clientY<0 || event.altKey) //event.altKey表示按下了Alt按纽
{
document.all('ButtonPageClose').click();
document.all('ButtonPageClose').focus();
}
}
</ script >
</ head >
< body onbeforeunload = " PageClose() " >
按纽里的方法同上面一样,也是取消会话。
这个方法我测试了,好象基本上可以,但是又好象有时没调用到,好象是和用户点击按纽的位置有关。