技术文章 > ASP.NET中实现在线用户检测(使用后台守护线程)

ASP.NET中实现在线用户检测(使用后台守护线程)

2018-11-15 10:15

文档管理软件,文档管理系统,知识管理系统,档案管理系统的技术资料:


日期:2005-6-12 12:12:00 来源: 编辑: 26     [全屏查看全文]

以下是我的类文件,
//online.cs(用户在线检测)
/*程序实现思路:
该用户有以下几个属性:
name:用户名
sessionID:用户ID,通过它唯一表示一个用户
iswhere :附加信息,用户当前所在位置
lasttime:用户登陆时间
curtime:本次刷新时间
在客户端,使用一个IFRAME,装载一个刷新页面,每隔XX秒更新一下他的名字对应的curtime,就表示他仍然在
在服务器端,建立一个守护线程,每隔固定时间就运行一遍,然后判断当前所有用户列表中的时间间隔是否超出了
规定的时间,如果超出,则将该用户从在线列表中删除,这样就可以做到检测用户是否在线了,而如果再单独
写个用户离线后的处理,就可以解决好多人问到的:用户意外吊线后的处理。
*/
#define _debug
namespace Soholife
{
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections ;
using System.Threading ;
using System.Web;
using System.Diagnostics;


//定义了一个结构
public struct User
{
public string name;
public DateTime lasttime;
public DateTime curtime;
public string sessionid;
public string iswhere;
}

//定义在线用户类
public class OnLineUser
{
private static ArrayList _alluser ; //定义用户

public ArrayList alluser
{
get{return _alluser;}
set{_alluser=value;}
}

public OnLineUser() //构造函数
{
if(_alluser==null)
{
_alluser=new ArrayList();
}
}
//功能说明:将当前用户加入在线列表
//如果该用户的数据当前仍然在在线列表中,则暂时先不让该用户登陆,提示用户存在
public bool AddUserToOnLine(User user)
{
//需要先判断用户是否已经在用户列表中了
if(_alluser==null)
{
_alluser.Add(user);
return (true);
}
else
{
for ( int i = 0 ; i < _alluser.Count ; i ++)
{
//循环判断用户是否已经存在
Soholife.User tempuser = (Soholife.User)_alluser[i] ;
if(tempuser.sessionid.Equals(user.sessionid) && tempuser.name.Equals(user.name))
{
return(false); //用户已经存在,则直接退出
}
}
_alluser.Add(user);
return (true);
}
}

//功能说明:判断某用户是否在线,本部分暂时不用
//返回值:TRUE代表在线,FALSE不在
public Boolean IsUserOnLine(string name)
{
//需要先判断用户是否已经在用户列表中了
if(_alluser==null)
{
return (false);
}
else
{
for ( int i = 0 ; i < _alluser.Count ; i ++)
{
//循环判断用户是否已经存在
Soholife.User tempuser = (Soholife.User)_alluser[i] ;
if(tempuser.name.Equals(name))
{
return(true) ;
}
}
return (false);
}
}

//功能说明:更新用户在线时间
//返回值:最新的在线用户列表
public Boolean CheckUserOnLine(string name)
{
//需要先判断用户是否已经在用户列表中了
if(_alluser!=null)
{
for ( int i = 0 ; i < _alluser.Count ; i ++)
{
Soholife.User tempuser = (Soholife.User)_alluser[i] ;
//先判断当前用户是否是自己
if(tempuser.name.Equals(name))
{
//更新用户在线时间
tempuser.curtime=DateTime.Now;
alluser[i]=tempuser;
return(true);
}
}
}
return(false);
}
}



/*
下面开始建立守护线程类:
(注:此处,开始写的时候本来想做成单件模式的,不过由于以前没有做过这个东西,所以反而发生
了很多问题,最后决定放弃而使用现有的格式,不过,刚才从开心那里有对单件有个认识,晚上回去
会再去用用它写另一种模式 )
*/
public class CheckOnline
{
const int DELAY_TIMES = 5000 ; //定义执行的时间间隔为5秒
const int DELAY_SECONDS=30; //将用户掉线时间设置为30秒

private Thread thread ; //定义内部线程
private static bool _flag=false; //定义唯一标志

public CheckOnline()
{
if (!_flag)
{
_flag= true;
this.thread = new Thread(new ThreadStart(ThreadProc)) ;
thread.Name = “online user“ ;
thread.Start() ;
}
}


internal void ThreadProc()
{
while(true)
{
Soholife.OnLineUser temp=new Soholife.OnLineUser(); //定义一个用户对象
for (int i=0 ;i< temp.alluser.Count;i++)
{
User tmpuser=(User)temp.alluser[i];
//我是将该用户的最新时间加上80秒,然后和当前时间比较,小与当前时间,
//则表示该用户已经吊线,则删除他的记录
if(tmpuser.curtime.AddSeconds(DELAY_SECONDS).CompareTo(DateTime.Now)<0)
{
temp.alluser.RemoveAt(i);
}
}
Thread.Sleep(DELAY_TIMES) ;

}
}
}
}

有了DLL剩下的就是在页面中使用了
我没有针对那个系统特定的去做,读者可以自己将他加如任何一个系统
使用中只要新建立个用户:User newuser=new User();
然后将这个用户加入用户列表中就可以了
由于我没有什么固定用户,测试程序中就用的是sessionid做的用户名
程序如下
//global.aspx
<%@Import namespace=“System“%>
<%@Import namespace=“Soholife“%>
<%@Import Namespace=“System.Collections“%>
<script language=“C#“ runat=“server“>
void Session_Start(Object sender, EventArgs E)
{
//得到在线用户列表
User newuser=new User();
newuser.name=Session.SessionID ;
newuser.sessionid=Session.SessionID ;
newuser.lasttime=newuser.curtime=DateTime.Now;

OnLineUser alluser= new OnLineUser();
if(alluser.AddUserToOnLine(newuser))
{
Response.Write (“用户添加成功<br>“);
}
else
{
Response.Write (“用户添加失败<br>“);
}

}
void Session_End(Object sender, EventArgs E) {

}


void Application_Error(Object sender, EventArgs E) {
// Context.ClearError();
// Response.Redirect(“errorpage.htm“);
}
</script>
启动后台线程可以用下面的语句:
CheckOnline online=new CheckOnline();
用户可以将它放到GLOBAL。ASAX中,我是没有了,只放到了一个ASPX文件中做简单的测试。如下
//start.aspx
<%@ Page Language=“c#“ autoEventWireup=true Debug=“true“ %>
<%@ Assembly Name=“Soholife“ %>
<%@Import Namespace=“System“%>
<%@Import Namespace=“Soholife“%>
<%@Import Namespace=“System.Collections“%>

<script runat=“Server“ Language=“C#“>
void Page_Load(Object sender, EventArgs args)
{
CheckOnline online=new CheckOnline();
}
</script>

<html><head>
<style type=“text/css“>
td{font-size:12;}
.bgcolor{background:#ffffcc;}
</style>
</head>
<body><center>

</center></body></html>

而我们还需要一个程序来显示当前在线拥护的数据,程序如下:
//online.aspx
<%@ Page Language=“c#“ autoEventWireup=true Debug=“true“ %>
<%@ Assembly Name=“Soholife“ %>
<%@Import Namespace=“System“%>
<%@Import Namespace=“Soholife“%>
<%@Import Namespace=“System.Collections“%>

<script runat=“Server“ Language=“C#“>
void Page_Load(Object sender, EventArgs args)
{
OnLineUser temp= new OnLineUser();

ArrayList alluser =temp.alluser;
string str=““;
str += “<tr bgcolor=#ffff99>“;
str += “<td width=100 align=center class=coolbar>用户</td>“;
str += “<td align=center width=150 class=coolbar>登陆时间</td>“;
str += “<td align=center width=150 class=coolbar>最近时间</td>“;
str += “<td width=100 height=20 class=coolbar>当前位置</td>“;
str += “</tr>“;


for ( int i = 0 ; i < alluser.Count ; i++)
{
Soholife.User tempuser=(Soholife.User)alluser[i] ;
str += “<tr bgcolor=white>“;
str += “<td>“ + tempuser.name + “</td>“;
str += “<td>“ + tempuser.lasttime + “</td>“;
str += “<td>“ + tempuser.curtime + “</td>“;
str += “<Td>“ + tempuser.iswhere + “</td>“;
str += “</tr>“;
}
maininfo.Text=str;
}
</script>

<html><head>
<style type=“text/css“>
td{font-size:12;}
.bgcolor{background:#ffffcc;}
</style>
<script language=javascript>
function openwindow(url,w,h)
{
window.open(url,““,“toolbar=no,menubar=no,directories=no,status=yes,width=“ + w + “,height=“ + h + “,scrollbars=yes,resizable=yes“);
return false;
}
</script>
</head>
<body bgcolor=“#ccffcc“><center>
<Br>
<table width=450 bgcolor=white cellpadding=“0“ cellspacing=“0“ style=“border:none“;>
<Tr><td colspan=2 align=center class=bar>当前在线用户</td></tr>
</table><br>
<asp:Label font-size=“8pt“ id=“showmsg“ runat=“server“/>
<table width=450 bgcolor=white cellpadding=“2“ cellspacing=“1“ class=“Grid“>
<asp:Label font-size=“8pt“ id=“maininfo“ runat=“server“/>
</table>
</center></body></html>