新微赢技术网

标题: ASP.NET实现用户在线检测的类源码 [打印本页]

作者: qz沒愛過mm    时间: 2009-3-16 18:05
标题: ASP.NET实现用户在线检测的类源码
//online.cs(用户在线检测)
/*程序实现思路:

该用户有以下几个属性:
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)  ;
                        }
                }
作者: huangbo88    时间: 2009-11-8 14:05
这篇帖子构思新颖,题材独具匠心,段落清晰,情节诡异,跌宕起伏,主线分明,引人入胜!




欢迎光临 新微赢技术网 (http://bbs.weiying.cn/) Powered by Discuz! X3.2