/*程序实现思路:
该用户有以下几个属性:
name:用户名
sessionID:用户ID,通过它唯一表示一个用户
iswhere;;:附加信息,用户当前所在位置
lasttime:用户登陆时间
curtime:本次刷新时间
在客户端,使用一个IFRAME,装载一个刷新页面,每隔XX秒更新一下他的名字对应的curtime,就表示他仍然在
在服务器端,建立一个守护线程,每隔固定时间就运行一遍,然后判断当前所有用户列表中的时间间隔是否超出了规定的时间,如果超出,则将该用户从在线列表中删除,这样就可以做到检测用户是否在线了,而如果再单独
写个用户离线后的处理,就可以解决好多人问到的:用户意外吊线后的处理。
*/
#define;;DEBUG
using;;System;
using;;System.Data;
using;;System.Data.SqlClient;
using;;System.Collections;;;
using;;System.Threading;;;
using;;System.Web;
using;;System.Diagnostics;
namespace;;SohoProject
{
//定义了一个结构
public;;struct;;User
{
public;;string;;name;
public;;DateTime;;lasttime;;;;;
public;;DateTime;;curtime;
public;;string;;sessionid;
public;;string;;ip;
public;;string;;iswhere;
}
public;;class;;OnLineUser
{
private;;static;;DataTable;;_alluser;
//只读属性
public;;DataTable;;alluser{
get{return;;_alluser;}
}
public;;OnLineUser()
{
if(_alluser==null)
{
//define;;user;;list;;
//;;Declare;;variables;;for;;DataColumn;;and;;DataRow;;objects.
_alluser;;=;;new;;DataTable("onlineuser");
DataColumn;;myDataColumn;
//;;Create;;new;;DataColumn,;;set;;DataType,;;ColumnName;;and;;add;;to;;DataTable.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.String");
myDataColumn.ColumnName;;=;;"name";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"name";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;false;
_alluser.Columns.Add(myDataColumn);
//;;Create;;sessionid;;column.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.String");
myDataColumn.ColumnName;;=;;"sessionid";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"sessionid";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;true;
_alluser.Columns.Add(myDataColumn);
//;;Create;;ip;;column.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.String");
myDataColumn.ColumnName;;=;;"ip";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"ip";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;false;
_alluser.Columns.Add(myDataColumn);
//;;Create;;iswhere;;column.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.String");
myDataColumn.ColumnName;;=;;"iswhere";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"iswhere";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;false;
_alluser.Columns.Add(myDataColumn);
//;;Create;;iswhere;;column.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.DateTime");
myDataColumn.ColumnName;;=;;"lasttime";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"lasttime";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;false;
_alluser.Columns.Add(myDataColumn);
//;;Create;;iswhere;;column.
myDataColumn;;=;;new;;DataColumn();
myDataColumn.DataType;;=;;System.Type.GetType("System.DateTime");
myDataColumn.ColumnName;;=;;"curtime";
myDataColumn.AutoIncrement;;=;;false;
myDataColumn.Caption;;=;;"curtime";
myDataColumn.ReadOnly;;=;;false;
myDataColumn.Unique;;=;;false;
_alluser.Columns.Add(myDataColumn);
}
}
//功能说明:将当前用户加入在线列表
//如果该用户的数据当前仍然在在线列表中,则暂时先不让该用户登陆,提示用户存在
public;;bool;;;;AddUserToOnLine(User;;user)
{
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc("开始进入<将当前用户加入在线列表>....");
(new;;SohoProject.SohoDebug()).WriteToDoc("/r/n");
#endif
//开始搜索是否已经存在该用户,如果存在则是改变数据,否则添加新的用户
string;;strExpr;
strExpr;;=;;"sessionid='";;+;;user.sessionid;;+;;"'";;;
DataRow[];;curUser;
//;;Use;;the;;Select;;method;;to;;find;;all;;rows;;matching;;the;;filter.
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc("搜索字符串:";;+;;strExpr);
(new;;SohoProject.SohoDebug()).WriteToDoc("/r/n");
#endif
curUser;;=;;_alluser.Select(strExpr);
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc(strExpr);
(new;;SohoProject.SohoDebug()).WriteToDoc(curUser.Length.ToString());
#endif
if;;(curUser.Length;;>0;;)
{
for(int;;i;;=;;0;;;i;;<;;curUser.Length;;;i;;++)
{
curUser[i]["curtime"]=DateTime.Now;
curUser[i]["iswhere"]=user.iswhere;
}
}
else
{
//直接加入新的数据
DataRow;;myRow;
try
{
myRow;;=;;_alluser.NewRow();
//;;Then;;add;;the;;new;;row;;to;;the;;collection.
myRow["name"];;=;;user.name;
myRow["ip"];;=;;user.ip;
myRow["iswhere"];;=;;user.iswhere;
myRow["lasttime"];;=;;user.lasttime;
myRow["curtime"];;=;;DateTime.Now;
myRow["sessionid"];;=;;user.sessionid;
_alluser.Rows.Add(myRow);
}
catch(Exception;;e)
{
throw(new;;Exception(e;;+;;"--------------------";;+;;;;e.ToString()));;;
};;
}
_alluser.AcceptChanges();
return;;true;
};;;;
//功能说明:判断某用户是否在线,本部分暂时不用
//返回值:TRUE代表在线,FALSE不在
public;;;;Boolean;;IsUserOnLine(string;;name)
{
//需要先判断用户是否已经在用户列表中了
//开始搜索是否已经存在该用户,如果存在则是改变数据,否则添加新的用户
string;;strExpr;
strExpr;;=;;"name;;='";;+;;name;;+;;"'";;;
DataRow[];;curUser;
//;;Use;;the;;Select;;method;;to;;find;;all;;rows;;matching;;the;;filter.
curUser;;=;;_alluser.Select(strExpr);
if;;(curUser.Length;;>0;;)
{
return;;true;
}
else
{
return;;false;
}
}
//功能说明:更新用户在线时间
//返回值:最新的在线用户列表
public;;Boolean;;CheckUserOnLine(string;;name,string;;iswhere,string;;sessionid,string;;ip)
{
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc("开始进入检查用户方法....");
(new;;SohoProject.SohoDebug()).WriteToDoc("");
#endif
//需要先判断用户是否已经在用户列表中了
User;;newuser=new;;User();
newuser.name=;;name;
newuser.iswhere=;;iswhere;
newuser.lasttime=newuser.curtime=DateTime.Now;
newuser.sessionid=sessionid;
newuser.ip=ip;
OnLineUser;;alluser=;;new;;OnLineUser();
alluser.AddUserToOnLine(newuser);
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc("离开检查用户方法....");
#endif
return;;true;
}
}
//定义在线用户类
public;;class;;OnLineUser_old
{
private;;static;;ArrayList;;_alluser;;;;;;;//定义用户
public;;ArrayList;;alluser
{
get{return;;_alluser;}
set{_alluser=value;}
}
public;;OnLineUser_old();;;;//构造函数
{
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;;++)
{
//循环判断用户是否已经存在;;;;;;SohoProject.User;;tempuser;;=;;(SohoProject.User)_alluser[i];;;
if(;;tempuser.sessionid.Equals(user.sessionid))
{
//更新用户在线时间
tempuser.name=user.name;
tempuser.curtime=DateTime.Now;
tempuser.iswhere=user.iswhere;
tempuser.sessionid=user.sessionid;
tempuser.ip=user.ip;
alluser[i]=tempuser;
return(true);
//return(true);;;//用户已经存在,则直接退出;;;;;;}
}
_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;;++)
{
//循环判断用户是否已经存在;;;;;;SohoProject.User;;tempuser;;=;;(SohoProject.User)_alluser[i];;;
if(tempuser.name.ToLower().Equals(name.ToLower()))
{
return(true);;;
}
}
return;;(false);
}
}
//功能说明:更新用户在线时间
//返回值:最新的在线用户列表
public;;Boolean;;CheckUserOnLine(string;;name,string;;iswhere,string;;sessionid,string;;ip)
{
//需要先判断用户是否已经在用户列表中了
if(_alluser!=null)
{
User;;newuser=new;;User();
newuser.name=;;name;
newuser.iswhere=;;iswhere;
newuser.lasttime=newuser.curtime=DateTime.Now;
newuser.sessionid=sessionid;
newuser.ip=ip;
//OnLineUser;;alluser=;;new;;OnLineUser();
AddUserToOnLine(newuser);
}
return(false);
}
}
/*
下面开始建立守护线程类:
(注:此处,开始写的时候本来想做成单件模式的,不过由于以前没有做过这个东西,所以反而发生
了很多问题,最后决定放弃而使用现有的格式)
*/
public;;class;;CheckOnline;;
{
const;;int;;DELAY_TIMES;;=;;10000;;;//定义执行的时间间隔为5秒
const;;int;;DELAY_SECONDS=60;;;//将用户掉线时间设置为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);;;;
{
//;;;;SohoProject.OnLineUser;;temp=new;;SohoProject.OnLineUser();;;;;//定义一个用户对象
//;;;;for;;(int;;i=0;;;i<;;temp.alluser.Count;i++)
//;;;;{
//;;;;;;User;;tmpuser=(User)temp.alluser[i];
//;;;;;;//我是将该用户的最新时间加上30秒,然后和当前时间比较,小与当前时间,
//;;;;;;//则表示该用户已经吊线,则删除他的记录
//;;;;;;if(tmpuser.curtime.AddSeconds(DELAY_SECONDS).CompareTo(DateTime.Now)<0);;
//;;;;;;{
//temp.alluser.RemoveAt(i);
//;;;;;;}
//;;;;}
SohoProject.OnLineUser;;temp=new;;SohoProject.OnLineUser();;;;;//定义一个用户对象
//开始检查是否有用户过期了string;;strExpr;
//tmpuser.curtime.AddSeconds(DELAY_SECONDS).CompareTo(DateTime.Now)<0
strExpr;;=;;"curtime;;<;;'";;+;;DateTime.Now.AddSeconds(;;0;;-;;DELAY_SECONDS);;+;;"'";;;
#if;;DEBUG
(new;;SohoProject.SohoDebug()).WriteToDoc(strExpr);
#endif
DataRow[];;curUser;
//;;Use;;the;;Select;;method;;to;;find;;all;;rows;;matching;;the;;filter.
curUser;;=;;temp.alluser.Select(strExpr);
if;;(curUser.Length;;>0;;)
{
//删除这些记录
for(int;;i;;=;;0;;;i;;<;;curUser.Length;;;i;;++)
{
curUser[i].Delete();
}
temp.alluser.AcceptChanges();
}
Thread.Sleep(DELAY_TIMES);;;
}
}
}
}
标签: