2013-03-05 62 views
3

我正在构建一个使用servlet的java网页游戏。 我需要知道当用户不回答30个secundes,我使用识别会话超时

session.setMaxInactiveInterval(30); 

但我需要知道在服务器端,一旦时间结束了,所以我可以让这个播放器相当。

现在,一旦玩家返回并尝试做某件事,他将获得超时时间,并且我可以在服务器上看到。

一旦会话超时,我该如何知道servlet?

谢谢。

回答

13

您需要实现HttpSessionListener接口。它在会话创建或销毁时接收通知事件。特别是,当会话被销毁时,它的方法sessionDestroyed(HttpSessionEvent se)被调用,这发生在超时时间结束/会话失效后发生。您可以通过呼叫HttpSessionEvent#getSession()获取会话中存储的信息,稍后可以根据会话进行必要的安排。此外,在web.xml一定要注册您的会话监听器:

<listener> 
    <listener-class>FQN of your sessin listener implementation</listener-class> 
</listener> 

如果你最终要失效,你可以使用下面的行监听器会话超时来区分:

long now = new java.util.Date().getTime(); 
boolean timeout = (now - session.getLastAccessedTime()) >= ((long)session.getMaxInactiveInterval() * 1000L); 
+0

谢谢,但在这以及在浏览器中刷新之后,我只能访问 sessionDestroyed() 。 或者我做错了什么? – YotamB 2013-03-05 13:23:28

+0

你不需要对会话超时做任何事情,比如操纵浏览器,你的servlet容器会为你处理这种情况。请注意,在超时期限结束后,该会话将不会完全收集*。 servlet容器检查超时*的会话,并且在找到有资格销毁的会话时触发侦听器方法并销毁会话。 – skuntsel 2013-03-05 13:48:16

0

我结束了使用HttpSessionListener并在大于setMaxInactiveInterval的时间间隔内刷新。

因此,如果在40秒之后的下一次刷新中,30秒使用什么都没做,我就到sessionDestroyed()。

同样重要的是,您需要创建新的ServletContext才能到达ServletContext。

ServletContext servletContext=se.getSession().getServletContext(); 

谢谢!

+0

所以你解决了这个问题? – 2013-03-05 15:10:45

+0

考虑一个用户打开两个浏览器标签20秒 - 如果你不小心,这种安排可能导致他们*永远不会被注销。 – 2017-05-31 21:38:56

0

基于空闲间隔猜测的替代方法是在用户触发注销时设置会话中的属性。例如,如果你可以把类似的在处理用户触发注销的方法如下:

httpServletRequest.getSession().setAttribute("logout", true); 
// invalidate the principal 
httpServletRequest.logout(); 
// invalidate the session 
httpServletRequest.getSession().invalidate(); 

,那么你可以在你的HttpSessionListener类以下内容:

@Override 
public void sessionDestroyed(HttpSessionEvent event) { 
    HttpSession session = event.getSession(); 
    if (session.getAttribute("logout") == null) { 
     // it's a timeout 
    } 
}