4

当用户登录到我的 Web 应用程序时,我会创建一个会话:

session.setAttribute("SessionNumber","100");

并且他的用户名被添加到一个名为ONLINE_USERS. Other Online users 的表中就能看到他,他们看到所有在线用户

当用户单击注销按钮时,我从表中删除该行,然后使用以下命令删除会话:

session.invalidate();

但是假设用户存在浏览器,他的会话将消失,但该行将作为在线用户留在数据库中,如何避免这种情况?

我在 Netbeans 上使用 JSP-Servlets。

4

3 回答 3

6

您可以启用自定义HttpSessionListener以在会话失效时删除表行。

public class YourHttpSessionListener implements HttpSessionListener {       
   public void sessionCreated(HttpSessionEvent event) {
   //put row in the database
   }

   public void sessionDestroyed(HttpSessionEvent event) {
     //delete the row from database     
   }
}

在 web.xml 中声明监听器:

<listener>
    <listener-class>YourHttpSessionListener</listener-class>
</listener>

请注意,在用户退出浏览器和他的会话在服务器上过期之间会有延迟。但是会话过期时间是可配置的。你应该找到一个合适的过期时间:不要太长,这样你就不会将太多的离线用户显示为在线,但不要太短,让连接的用户有空闲时间。

servlet我认为这对于使用基础和jsp技术开发的聊天应用程序来说是一个很好的权衡。

于 2012-09-01T21:05:35.193 回答
1

据我了解,您希望看到目前正在网站上操作的用户,HttpSessionListener 的问题是会话在其被销毁之前可以存活很长时间,因此用户可能会在被销毁时长时间不使用该网站. (见http://www.smartsoftwarebits.com/qaa/46-misc/82-how-to-set-session-timeout-for-tomcat

解决方案:您可以在数据库中添加一列,您将在其中存储用户发出的最后一次请求的时间戳。要使此列保持最新,请使用 servlet 过滤器。(http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html

要清除在线用户,请添加一个计时器作业(例如使用石英),您将在其中删除早于(例如)5 分钟的行(在线用户)(因此当最后一次交互超过 5 分钟时)(http://石英调度器.org/

使用它,您现在可以非常准确地判断是否有用户“仍然存在”。

此外,您可以向客户端 javascript 添加一个计时器,以定期进行 ajax 调用。您可以通过这种方式处理用户没有关闭浏览器只是暂时处于非活动状态的情况。

于 2012-09-01T23:16:39.480 回答
1

首先是在浏览器关闭时捕获事件

您可以尝试在您的 jsp 中使用下面的代码片段来命中一个 js 函数,该函数将调用一个 ajax 函数来命中服务器端组件。然后只需使用会话 API 使会话无效并添加代码以从表中删除记录。

window.onbeforeunload = WindowClose; 

function WindowClose() { 

  //Write a AJAx request here to hit the server side servlet  to invalidate the session

}

或使用

<body onunload="WindowClose(); >

在服务器端代码中,使用

HttpSession 会话 = request.getsession(); session.setMaxInactiveInterval(0); //或 session.invalidate();

在 web.xml 中定义默认会话超时值将是一个很好的方法,以便在浏览器崩溃时,会话将在规定的时间过去后失效。

<session-config>
<session-timeout>30</session-timeout>
</session-config>
于 2012-09-02T12:45:14.357 回答