同一账号多次登录

在WEB应用程序中,如果想做这样一个功能:
  在一个用户在A地登录后,另一个人用同一账号在B地登录,那么就要提示此账号正在被使用。
 
 思路:
  1、在Session开始时,也就是第一次成功登录时,给Session值,同时,把这个值添加到Application中。
  2、众所周知,Session是一个会话,也就是说是一个人所拥有的,而Application则是整个网站所共公的,
   把所有登录的账号都存在Application中,用它来判断相应的账号是否已经存在,也就是说是否已经登录过了。
   到这里,第1步,第一次登录的时候就得加点东西,得判断一下Application中有没有这个账号,如果有,那么就提示不能登录;
   如果没有,那么就给Session值,同时,把这个值加到Application中去。
  3、当然,只是在Application中加东西,不清除它可是不行的,这样的话一个用户只能登录一次了,要想下一次登录就得重起一下Server了,
   在什么时候清除它呢,当用户退出的时候,对,当用户退出时,清除Session,这样会触发Global.asax中的Session_End事件,
   在这个事件中清除登录的账号。这样,用户退出时,清除,登录时,先判断,后确定能不能登录,并确定是否添加进Application。
   一个完美的计划产生了,不过,事情往往不是想得这样简单的。
  4、前面的想法只是理想主义,我相信没有多少人在用完系统后,会认真地去点一下那个“退出”,多半是直接在IE的叉叉上一点,
   还有更酷的是,按一下ALT+F4,这种情况下,如果把Session的时间设得过大,那这个用户突然想起还有点事情没做完,那是不是要让用户
   去抽支烟再来呢,如果把Session时间设得过小,用户正在添加数据或是写文章的时候,当提交时,由于Session过期而显示一个登录界面,
   可能用户不气死也要气疯了吧。
  5、有人马上说:在关闭IE时处理一下撒!好主意!onbeforeunload这个事件正是在页面卸载前触发的,这里可以做下手脚,
       function window.onbeforeunload()
    {
     if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey)
     {
            window.open("logout.aspx");
         }
     }
   在logout.aspx的Page_Load事件中清除Session和Application,当然还得在logout.aspx的onload中加点JS:onload="javascript:window.close()"
   看起来差不多了吧,现在有两个地方清除Application了,不过,这样试一下,点IE的文件->退出,不难发现,和想的有点不对了,这样不能触发JS的事件。
  6、还有什么招吗?看来得放弃第5步中所说的方法了。
   再回到第4步中的想一下,Session的时间不能设得太大,也不能设得太小,这个合适就不好把握了。
   有高人提示到:在客户端一直激活它不就行了吗,当用户没激活时,也就表示Session过期了撒~
   真是高人!
   在客户端激活Session,可能最先想到的是要用AJAX,正是!首先来创建一个异步访问对象:
   var httpRequest;   
   function CreateXmlHttpRequest()
   {
    httpRequest = false;
    if(window.XMLHttpRequest)
    {//Mozilla浏览器
     httpRequest = new XMLHttpRequest();
     if(httpRequest.overrideMimeType)
     {
      httpRequest.overrideMimeType("text/xml");
     }
    }
    else if(window.ActiveXObject)
    {//IE浏览器
     try
     {
      httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
     }
     catch(e)
     {
      try
      {
       httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      }           
      catch(e)
      {
      
      }
     }
    }
    if(!httpRequest)
    {
     window.alert("Can't Create XMLHttpRequest");
     return false;
    }
   }
   再来个方法来调用它:
    var x=1;
    function myRefresh()
    {
         if(CreateXmlHttpRequest() != false)
         {
            httpRequest.open("GET", "Default3.aspx", true);
            httpRequest.send(null);
         }
        x++;
        if(x<=2) //真正的过期时间
        {
            setTimeout("myRefresh()",30*1000); //30秒
        }
    }
  这样,一开始就调用这个方法,那么就等于页面不停地在请求这个页面了:myRefresh();
  而在Default3.aspx中,只要在Page_Load事件中加一行:Response.Expires = -1;
  同时,在Web.Config中写个小小的配置:<sessionState mode="InProc" timeout="1"></sessionState>
  就可以了,注意那个x,它表示一共调用多少次,也就是Session过期的时间是多少,这里就得看自己的项目了,设多大自己看着办吧。
  按照这个做法,当用户登录后,
  (1)、马上关掉这个页面,这时,Session的过期时间是1分钟,相信这1分钟不会太久吧~
   过了1分钟,Session就会过期,自然就会触发上面所说的Session_End事件,这样就可以清除Application了。
  (2)、不关掉页面,我就这么一直耗着,如果上面的x设得够长的话,Session会到很长的时间才会过期(1小时左右吧),
   一小时都不做任何操作,可能用户真的是睡着了吧,这样叫你再登录一次不过分吧!
   当然在这1小时内,你有任何的操作,x会重新计数的,也就是说用户在最后一次操作过了1小时后,才会过期,
   当然在这1小时内,你直接关掉IE,1分钟后Session自然会过期了,
  别忘了这里的主题是在当前账号使用的同时其它人不能使用,这里也就达到了这个效果,在这1小时内,其它人是登录不进来的~
  
  
posted @ 2008-03-26 13:12  point.deng  阅读(1351)  评论(0编辑  收藏  举报