有点长,大家不要急哈新手,无经验,不知道大家都如何处理这个问题,求教了刚才自己想了想,不知道行不行,首先我<sessionState cookieless="true" ></sessionState>,用户登录时将[sessionid/最后请求时间]存到cache,然后在某些用户停留时间长的页面上定时(比如说30秒)异步请求一个online.aspx页面,这个页面会更新最后请求时间并检查最后请求时间到现在的差值是否超过了某个指定的值(比如40秒),如果超过了,我就获取这个sessionid,并跳转到http://localhost:8080/abc/(S(sessionid))/logout.aspx,在这个页面用这个session来完成他的正常退出程序现在想想貌似有问题网上看到有人说,客户端代码判断用户关闭浏览器,然后用批处理文件销毁Session ,不过没看懂,也求解

解决方案 »

  1.   

    关闭浏览器就已经是摧毁Session了事实上我觉得思路错了应该判断最后活跃时间,超过多长没活动,自动退出
      

  2.   

    数据库记录用户登录状态,ajax timer修改登录时间
    超时修改用户登录状态
      

  3.   


    我以前也这么觉得啊,可是越想越不对,客户端关了浏览器,实际上服务器端的该客户的session还应该存在一段时间吧,直到过期,只不过没有人会用到他了而已还有我怎么能使他退出呢
      

  4.   

    关闭浏览器是正常退出,默认是自动清session的
    非正常退出只的是电脑死机浏览器非法关闭之类的情况
    你应该把退出方法写在Global.asax的Session_End事件里
      

  5.   

    你确定吗?服务器根本不会有机会知道浏览器已经关闭,所以session还是存在的,所以用户关闭浏览器再马上重新打开浏览器登录系统的话,系统就会告诉我,这个用户已经在线,不允许登录
    如果写在Session_End里也一样吧,要等session过期
      

  6.   

    写到Session_End就行   非正常关闭 就等session过期时执行
      

  7.   

    你换个思路看看:
    在可能非法关闭的页面中写JSwindow.onbeforeunload=function()
    {
          window.open("UpdateState.aspx","...");
    }再在UpdateState.aspx的初始化中写CS//你的操作(比如数据库操作)
    Session.Clear();再在UpdateState.aspx的初始化中写JS//初始化后在设定的毫秒数内自动关闭
    setTimeout("window.opener=null;window.open('','_self','');self.close()",500);
    //关闭时不弹对话框,IE6 IE7
    //window.opener=null; 
    //window.open('','_self'); 
    //window.close(); 
      

  8.   

    上面错了,重发
    你换个思路看看:
    在可能非法关闭的页面中写JSwindow.onbeforeunload=function()
    {
          window.open("UpdateState.aspx","...");
    }
    再在UpdateState.aspx的初始化中写CS//你的操作(比如数据库操作)
    Session.Clear();
    再在UpdateState.aspx的初始化中写JSwindow.onload=function()
    {
    //初始化后在设定的毫秒数内自动关闭
    setTimeout("window.opener=null;window.open('','_self','');self.close()",500);
    //关闭时不弹对话框,IE6 IE7
    window.opener=null; 
    window.open('','_self'); 
    window.close(); 
    }
      

  9.   


    你这样的应该是只关闭了浏览器的选项卡。 并没有把整个浏览器给关了。所以会提示已存在。。 这个是常见问题。 
    如果实直接关闭浏览器是会自动清除session的。
      

  10.   


    这个感觉可以试试 
    其实我们以前的项目就是做一个傻事。  就是每次人你家浏览首页或者是什么的时候 我们用一个xml里面的值和修改时间什么的来判断是否要执行操作。   比如按规律2个小时执行一次什么的!!
      

  11.   


    尽可能不要使用什么cookieless。除了根本不可能seo之外,也有太容易搅乱session(不懂软件的人也可以随便Ctrl+C/Ctrl+V去搅乱session)等问题。当Session集合中的数据全都“丢失”的时候,Session.SessionID不会丢失,所以没有必要。
    至于你的“正常退出程序”,我不知道干什么?用户下一次打开浏览器来浏览你的网站,那么他对应的SessionID也就变成新的了。互联网上的用户完全可能发呆40秒钟,你看这个csdn帖子也会发呆40秒钟,没有必要考虑什么“正常退出”。
      

  12.   

    这个方法也好啊,不过我试了下,如果这么写的话貌似刷新页面也会跳转,所以改成了window.onbeforeunload=function (){
        if(event.clientX<document.body.clientWidth && event.clientY < 0 || event.altKey)
        {
            window.open("UpdateState.aspx","...");
            //alert("test");
        }
    };可是吧
    这个方法是所有浏览器都支持的吗,不知道,需要验证
    而且这个方法在IE里使用,IE会限制访问,就是网页上边出一条那个东西,然后我允许了,可是也不好使呢,有解决办法吗
      

  13.   

    有些人做的幼稚asp.net程序,在Session数据丢失时就把用户导航到登录页面了,这很让人反感,特别是当程序部署到租来的asp.net虚拟机上时,也许刚开始租的时候每隔15分钟才丢失一次Session,但是等同一个服务器上网站多了、或者别的网站更新了、或者过节期间、或者空间商为了让服务器能够更加公平地保证系统稳定性,结果你的网站可能就突然变成每隔3、5分钟就会丢失一次Session集合中的数据了。合理的做法,就是根本不用Session集合保存数据。
      

  14.   

    发呆40秒钟就“退出程序”了?那么谁触发了这个判断?能够触发这个判断,说明用户根本还是在同一个 SessionID 编号,只是你的程序逻辑多此一举去给人家“退出”了。
      

  15.   

    那您的意思,就都用cookie啊什么的了嘛?
      

  16.   


    有的网页会定时发出异步请求,然后检查在线列表里的用户,如果列表里有用户长时间(40秒只是随便一说)没有请求,就算他关闭浏览器了,然后用/(S(sessionid))/logout.aspx来续用该用户的session,使其退出
    不过现在看来用不到了
      

  17.   

    另外,用户有各种需要判断为“退出”的方法,比如人家从浏览器地址栏上(或者其它任何方法影响了地址栏)输入新的地址,然后人家就去看别的网站了,最终也不回到你的应用程序,而是直接关闭了浏览器。还有直接shutdown浏览器进程。或者直接强行关闭电脑。或者(互联网上随时、上万次上百万次地发生)通讯中断了。等等。你的程序如果只是想当然地考虑一种,是没有意义的。
      

  18.   

    客户端不请求服务器,哪来的sessionid?如果请求,说“就算他闭了浏览器可”这个结论岂不是自相矛盾?
      

  19.   

    我可以告诉你的是,所谓的“清理垃圾数据”是这样的:服务器可以在Global.ascx中初始化一个Timer,每隔1个小时去清理一次数据库。而数据库中记录了每一个sessionid对应的最后一次活跃通讯的时间。而清理的原则,肯定不是什么40秒钟这种数值。你“随便一说”是必要的,至少我能搞清楚你心里是怎么想的,我能告诉你一个更准确的参考时间,比如是选择这个时间超过30分钟之后才清理。
      

  20.   


    您22,23L说的基本差不多一个意思,针对23L我说一下,这个sessionid本来是作为键值对的Key存到cache里或者Application里的,所以很好取到,每个用户登录时都会将存不过您说的会搞乱session这个问题,确实是,很严重,能不能通过改写URL来避免呢还有您16L说的,3,5,分钟就会丢失session,这个也太严重了,那我只能用cookie来代替了吗?
      

  21.   

    嗯,sorry,“在Global.ascx中初始化一个Timer,每隔1个小时”这个说法是有问题的。实际上它的目的是为了asp.net程序启动块一点,启动时不必立刻去清理垃圾,应该让Timer最初的Interval只是3秒钟,第一次清理之后才重新将Interval设置为较长的时间。
      

  22.   

    Session_End缺点SESSION经常丢失
    JS刷退出缺点是如果用任务栏右键关闭不会触发.
    自己写个SESSION功能,麻烦,但是实时性能高点.
      

  23.   


    这是Session管理的InProc模式的固有问题,msdn上关于应用程序状态管理中有专门说明。如果你可以确保自己完整拥有服务器,或者如果你做的asp.net应用是要卖给别人的并且用户永远都完整拥有自己的服务器,那么可以使用“Session状态服务器”或者使用SQL Server保存Session的模式。如果不是,那么个别简单类型的临时数据可以保存到cookie,复杂的临时数据当然是依靠数据库(使用sessionid来索引这些临时数据)。数据库操作可以在程序调通之后,使用数据缓存机制来优化。
      

  24.   

    举个例子,假设我们要查询某个SessionID对应的User对象是什么,可以写:
    public static class Bll
    {
      public static User 查询绑定到SessionID的User对象(string sessionid)
      {
         var uid=查询数据库返回用户id(sessionid);
         return 查询数据库返回用户信息(uid);
      }
    ........而用户登录也就是在数据库中记录下sessionid对应的userid。由于asp.net应用程序经常被动重启,也许用户刚刚看到一个页面,之后不足10秒钟就提交了内容,而这时asp.net刚刚重启,asp.net是使用新的进程处理这个提交操作的(因此Session集合、所有static内存变量等等数据都是初始化的)。因此一个好的asp.net程序是让用户感觉不到逻辑异常,它不会给用户导航到什么登录页面,因为Session.SessionID不会丢失,而程序依靠数据库来持久化保存会话中的复杂的需要持久化保存的信息。然后当你的程序调通,就可以随时优化一下性能:public static class Bll
    {
      public static User 查询绑定到SessionID的User对象(string sessionid)
      {
         var key=string.Format("SessionID {0} 绑定的用户对象",sessionid);
         var cache=HttpContext.Cache;
         var ret=(User)cache[key];
         if(ret==null)
         {
             var uid=查询数据库返回用户id(sessionid);
             ret=查询数据库返回用户信息(uid);
             cache.Insert(key,ret);   //你可以提供第三个参数,例如使用SqlDependency,或者以来其它Cache单元
         }
         return ret;
      }
    ........
    使用Cache,只是为了优化数据库操作,所以数据操作正确性依赖于数据库。那种先把数据放到内存中一段时间,然后才写到数据库的所谓缓存方法,是靠不住的,也不是正确的缓存方法。