java 关于单用户登录session问题,在线人数统计非正常退出系统问题

honey_Claire 2013-08-01 09:45:53
我做单用户登录时(java项目),把用户信息放在session里,并存在一个map里,当用户点击“退出”按钮时,再把map里的值删除,这样出现一个问题,就是用户如果直接关闭浏览器,没办法触发服务器清空session的方法,求做过的大神知道
...全文
707 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
如果非正常关闭浏览器无法解决,,那么只能通过session监听器来清空你的map了。。 http://blog.csdn.net/chenghui0317/article/details/9373345
yongxiaofeiche 2013-08-08
  • 打赏
  • 举报
回复
1楼是正解,用js完全没法实现这种功能。用户活跃时间必须在服务端验证。你可以在页面上做个定时器,定时给服务器发个请求,表示用户还在线。防止用户长时间没有操作,服务端误判把用户信息清除了。
honey_Claire 2013-08-08
  • 打赏
  • 举报
回复
引用 1 楼 l676331991 的回复:
当用户以登陆身份请求服务器资源时,记录用户的最后活跃时间。接着拟定一个失效时间,统计在线人数的时候,假设某个用户的最后活跃时间和当前时间的差值大于这个失效时间,也就是说该用户这一段时间都没有和服务器交互了,那么就认为该用户已下线,否则认为他是在线的。
貌似这个功能,都会存在瑕疵
honey_Claire 2013-08-08
  • 打赏
  • 举报
回复
我是这样做的:当一个人在一台电脑上登录了,然后非正常退出。再次登录的时候,判断是不是同一个ip,如果是的话,就让他登录,如果不是,则提示“该用户已登录”。这样做的弊端就是:session超时范围内,只能在一台电脑上登录
ILOVE_ASPNET 2013-08-05
  • 打赏
  • 举报
回复
引用 12 楼 l676331991 的回复:
对吧,ILOVE_ASPNET,如果要在线人数统计,就会出问题哦,onbeforeunload如果不可靠,像chrome下,onbeforeunload是没法判断出是直接关了浏览器还是页面跳转的,那么用户非正常离开系统,就没办法正确统计到人数了,系统就一直认为他在线呢?是不是呢?逻辑没错吧。 表激动哦,就技术论技术而已啦~~~
没激动,都是讨论技术交流,只是每个人看待问题点不一样,我知道你说的没错, 我把楼主的非正常退出理解成他直接 关闭浏览器右上角的x 关闭按钮,没理解成用任务管理器,或者其它方式关闭,这种情况说实话就只能按照你说的那样只能在服务端监控用户的状态 以及活跃时间段取决于更新操作。 而我的回答出发点可能不是你想的那样,所以才有了这么多的讨论,我回答这个问题的出发点是根据楼主1楼所提的,是否有正常关闭浏览器的方式 针对于 这个事件而进行讨论 ,这个是可以捕捉的 在这里可以直接修改状态为已下线, 至于你后面说的非正常的关闭情况 服务端肯定也是要时时监控的,这个时时我知道肯定不是每分每秒,当然也是定时的,根据需求来定义这个时间段, 这是后面的事情, 至于服务端如何根据定时的时间取决于用户是否还在线,你上面有提到了,每次上线会更新一个活跃时间,根据这个活跃时间判断就好。
l676331991 2013-08-03
  • 打赏
  • 举报
回复
引用 10 楼 ILOVE_ASPNET 的回复:
如果楼主需求是必须得时时监控 那就只能在服务端定时监控,多长时间 没做处理就认为已下线,这种是肯定只能在服务端做操作的, 我只是针对于楼主1楼的提问,认为他是想是不是没办法获取到浏览器直接关闭的事件, 这个是可以捕捉到的,才贴出了onbeforeunload , 至于用任务结束浏览哭,或者直接关电脑这种情况 就不要过于纠结了, 要看他需不需要时时监控,自己取决于 服务端还是客户端。
服务端可以用定时任务,不用时时统计。比如10分钟遍历一下在线用户表,清理一下那些非正常退出系统的家伙,把他们设置为下线。这样统计出来的在线人数,在一定时效误差允许下,才相对真实滴反应了系统的在线人数状况嘛。
l676331991 2013-08-03
  • 打赏
  • 举报
回复
对吧,ILOVE_ASPNET,如果要在线人数统计,就会出问题哦,onbeforeunload如果不可靠,像chrome下,onbeforeunload是没法判断出是直接关了浏览器还是页面跳转的,那么用户非正常离开系统,就没办法正确统计到人数了,系统就一直认为他在线呢?是不是呢?逻辑没错吧。 表激动哦,就技术论技术而已啦~~~
l676331991 2013-08-03
  • 打赏
  • 举报
回复
引用 10 楼 ILOVE_ASPNET 的回复:
如果楼主需求是必须得时时监控 那就只能在服务端定时监控,多长时间 没做处理就认为已下线,这种是肯定只能在服务端做操作的, 我只是针对于楼主1楼的提问,认为他是想是不是没办法获取到浏览器直接关闭的事件, 这个是可以捕捉到的,才贴出了onbeforeunload , 至于用任务结束浏览哭,或者直接关电脑这种情况 就不要过于纠结了, 要看他需不需要时时监控,自己取决于 服务端还是客户端。
ILove_ASPNET 别激动嘛,伦家楼主说的就是“java 关于单用户登录session问题,在线人数统计,非正常退出系统问题”,所以我才说那些的。 还有我只是怀疑onbeforeunload的可靠性而已,没有说思路不行呢。
ILOVE_ASPNET 2013-08-02
  • 打赏
  • 举报
回复
如果楼主需求是必须得时时监控 那就只能在服务端定时监控,多长时间 没做处理就认为已下线,这种是肯定只能在服务端做操作的, 我只是针对于楼主1楼的提问,认为他是想是不是没办法获取到浏览器直接关闭的事件, 这个是可以捕捉到的,才贴出了onbeforeunload , 至于用任务结束浏览哭,或者直接关电脑这种情况 就不要过于纠结了, 要看他需不需要时时监控,自己取决于 服务端还是客户端。
ILOVE_ASPNET 2013-08-02
  • 打赏
  • 举报
回复
引用 8 楼 l676331991 的回复:
[quote=引用 4 楼 ILOVE_ASPNET 的回复:] (4)如果用户直接关闭浏览器,可以在事件捕捉里面 根据你的要求看要不要去做处理,比如想修改此用户已下线,。
不知道阁下怎么能判断出直接关闭浏览器的,这个真有难度,或者说没法实现的。 阁下的意思是关闭windows意义下的窗口,而不是浏览器内部的tab吧,那么看看这个,打开的都是同一个网站。那么到底用户在关闭哪个的时候下线呢?“刷新非关闭,关闭非刷新”,其实正确判断出很难的,web应用的状态不能依赖这样的前端检测,web应用的用户在线状态是依赖后端语言的session会话机制的。 用户恶意退出,这个在技术层面根本检测不到。万一浏览器直接崩溃呢?windows蓝屏?操作系统瘫痪死机?客户机器突然断电?这些都可能导致用户意外退出的,一个onbeforeunload也是无力回天的。 因此,检测用户退出的动作,这个特别有难度。所以我才举出2#的做法,服务端用定时任务,检测用户在线状态,以辅助用户退出动作的捕获。 如果用户退出时web应用不需要做出额外的动作,那么完全不用理会这些,Session机制已经解决了这些意外下线的家伙的问题。 [/quote] 我真服了你, 用户正常的在系统 里面退出 和直接 关闭浏览器用onbeforeunload 捕捉 这种是可以知道的情况就更改下状态, 其它的比如用户直接用任务管理器结束掉,这种根本不用处理,你觉得有必要吗? 我结束到浏览器,下次再打开浏览器 在线,不用登录也很正常, 有cookie或者有session的时候就上线,没有就下线就行了,他这个又不是什么 特殊的需求,需要时时监控的, 至于那个状态说实话意义不是很大,不需要很准确,只是一个标识,没有登录就 登录下,有登录直接打开就好, 你要在服务端时时监控,你自己想下,客户端多了,你对每个都时时监控,你服务不死掉才怪。
l676331991 2013-08-02
  • 打赏
  • 举报
回复
引用 4 楼 ILOVE_ASPNET 的回复:
(4)如果用户直接关闭浏览器,可以在事件捕捉里面 根据你的要求看要不要去做处理,比如想修改此用户已下线,。


不知道阁下怎么能判断出直接关闭浏览器的,这个真有难度,或者说没法实现的。

阁下的意思是关闭windows意义下的窗口,而不是浏览器内部的tab吧,那么看看这个,打开的都是同一个网站。那么到底用户在关闭哪个的时候下线呢?“刷新非关闭,关闭非刷新”,其实正确判断出很难的,web应用的状态不能依赖这样的前端检测,web应用的用户在线状态是依赖后端语言的session会话机制的。

用户恶意退出,这个在技术层面根本检测不到。万一浏览器直接崩溃呢?windows蓝屏?操作系统瘫痪死机?客户机器突然断电?这些都可能导致用户意外退出的,一个onbeforeunload也是无力回天的。
因此,检测用户退出的动作,这个特别有难度。所以我才举出2#的做法,服务端用定时任务,检测用户在线状态,以辅助用户退出动作的捕获。
如果用户退出时web应用不需要做出额外的动作,那么完全不用理会这些,Session机制已经解决了这些意外下线的家伙的问题。
l676331991 2013-08-01
  • 打赏
  • 举报
回复
引用 2 楼 ILOVE_ASPNET 的回复:

      window.onbeforeunload = function () {

            var n = window.event.screenX - window.screenLeft;

            var b = n > document.documentElement.scrollWidth - 20;

            if (b && window.event.clientY < 0 || window.event.altKey) {

                alert("是关闭而非刷新");

                window.open(this.location);

            } else {

                alert("是刷新而非关闭");

            } 
        }
在这里面做处理吧
这样不行哦,先假设js能够正确判断刷新和关闭,当用户打开了多个标签页,只关闭其中一个,你就判断用户下线了,然后事实上用户没有下线,只关闭了一个标签页而已。 再说了,js根本没办法正确判断刷新和关闭,而且要考虑各种浏览器的兼容性。因此个人觉得这不属性js的范畴呢。
ILOVE_ASPNET 2013-08-01
  • 打赏
  • 举报
回复

      window.onbeforeunload = function () {

            var n = window.event.screenX - window.screenLeft;

            var b = n > document.documentElement.scrollWidth - 20;

            if (b && window.event.clientY < 0 || window.event.altKey) {

                alert("是关闭而非刷新");

                window.open(this.location);

            } else {

                alert("是刷新而非关闭");

            } 
        }
在这里面做处理吧
l676331991 2013-08-01
  • 打赏
  • 举报
回复
当用户以登陆身份请求服务器资源时,记录用户的最后活跃时间。接着拟定一个失效时间,统计在线人数的时候,假设某个用户的最后活跃时间和当前时间的差值大于这个失效时间,也就是说该用户这一段时间都没有和服务器交互了,那么就认为该用户已下线,否则认为他是在线的。
螃蟹k3179 2013-08-01
  • 打赏
  • 举报
回复
多标签和多浏览器是不同的。 而现在的大部分浏览器都是标签式(ie6除外),而且标签之间共享资源,比如cookie。 这个共享,服务器端是没办法检测到的。
ILOVE_ASPNET 2013-08-01
  • 打赏
  • 举报
回复
按照正常情况来说,单用户登录就不会存在 多个浏览器登录的情况了, 登录进去,修改下表的状态为已上线, 其它浏览器再登录时 发现这个状态为已上线,不让再登录就好, 至于同一个浏览器 里面登录的 就不用考虑选项页,只要考虑关闭浏览器,以及正常点击退出按钮 这二个操作就好, 至于是清除cookie还是session 就做相应处理就好,一般好点的是,session+cookie来进行存储的, 因为考虑到session会有丢失的情况。
螃蟹k3179 2013-08-01
  • 打赏
  • 举报
回复
不能再用户关闭浏览器上座监听,因为这个很多情况下监听不到。 比如非正常关闭。如果没监听到,那这个用户就永久在线了,这是不允许的。 支持2楼的做法。但最好有一个timer定时清理过期的用户,如果只在统计的时候清理,而且统计的次数不多的情况下会累积较多的信息,导致处理速度变慢。
ILOVE_ASPNET 2013-08-01
  • 打赏
  • 举报
回复
引用 3 楼 l676331991 的回复:
[quote=引用 2 楼 ILOVE_ASPNET 的回复:]

      window.onbeforeunload = function () {

            var n = window.event.screenX - window.screenLeft;

            var b = n > document.documentElement.scrollWidth - 20;

            if (b && window.event.clientY < 0 || window.event.altKey) {

                alert("是关闭而非刷新");

                window.open(this.location);

            } else {

                alert("是刷新而非关闭");

            } 
        }
在这里面做处理吧
这样不行哦,先假设js能够正确判断刷新和关闭,当用户打开了多个标签页,只关闭其中一个,你就判断用户下线了,然后事实上用户没有下线,只关闭了一个标签页而已。 再说了,js根本没办法正确判断刷新和关闭,而且要考虑各种浏览器的兼容性。因此个人觉得这不属性js的范畴呢。[/quote] 你怎么是这么理解的呢, 干嘛要关闭一个选项页就去判断一下用户是否下线,没必要这样, 我上面的代码是这么个意思, 让你捕捉到浏览器直接关闭的事件, 这样你可以在这个事件里面ajax去请求后台,去查表记录,然后决定是更新什么 数据, 不然你用什么 方式获取用户直接关闭浏览器的事件? 又怎么去修改表的状态? (1)你现在的问题就是 系统里面登录进去后,肯定有个登出按钮,当用户正常登出,你就去修改表的状态. (2)如果用户登录系统了,并且打开了多个选项页, 关闭每个选项页时,不要做任何处理, (4)如果用户直接关闭浏览器,可以在事件捕捉里面 根据你的要求看要不要去做处理,比如想修改此用户已下线, (4)如果用户用多个浏览器登录了,你考虑的太多了,没一个用户这么无聊,如果你要考虑的这么多,那你说咱办?是要清除还是不清除,要清除就清除,不清除就不清除,你根本没办法获取到用户用了哪几个浏览器登录过,没必要在登录之后还记录下你一共有哪几个浏览器登录过,然后还在关闭的时候去判断,你关了这个登录的浏览器,那另外如果有登录的浏览器 那咱办?要不要修改状态,你觉得是不是弄的太复杂了?

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧