如何检测浏览器关闭?

IT技术 javascript servlets
2021-03-13 02:26:55

在我的 Web 应用程序中,当用户登录时,我将他的 Id 添加到 servlet 中的有效 Id 向量中,当他注销时,我从向量中删除他的 Id,这样我就可以看到当前有多少用户处于活动状态,如果用户忘记注销,我的服务器生成的 html 有:

<meta http-equiv="Refresh" content="30; url=My_Servlet?User_Action=logout&User_Id=1111">

在标签中自动将他注销。

但我注意到许多用户永远存在,从未退出。我找到了原因,通过关闭浏览器,他们从不手动或自动注销,因此他们的用户 ID 永远不会从有效的用户 ID 向量中删除。

所以,我的问题是:如何检测用户关闭浏览器,以便我的 servlet 可以从向量中删除他们的 ID?


我在隧道尽头看到了一些亮光,但仍然存在问题,我的程序有这样的内容:

活跃用户列表:

User_1 : Machine_1 [ IP_1 address ]
User_2 : Machine_2 [ IP_2 address ]
User_3 : Machine_3 [ IP_3 address ]
...

我如何从会话侦听器中知道哪个用户的会话已结束并因此将他从我的列表中删除?

我希望当会话结束时,HttpServlet 的destroy()方法会被调用,我可以删除那里的用户 ID,但是当用户关闭浏览器时它永远不会被调用,为什么?当会话关闭时,HttpServlet 中是否还有其他方法被调用?

6个回答

无法在服务器端知道浏览器已关闭(除非您使用某些 JavaScript 向服务器发送消息)。怎么会有?想想 HTTP 是如何工作的——一切都是请求和响应。

但是,应用程序服务器会跟踪 Session 何时处于活动状态,甚至会告诉您 Session 何时被破坏(例如由于超时)。查看此页面以了解如何配置 aHttpSessionListener以接收这些事件。然后您可以简单地跟踪活动会话的数量。

活动会话的数量将落后于当前用户的实际数量,因为在会话超时之前必须经过一段(可配置的)时间;但是,这应该有点接近(您可以降低会话超时以提高准确性)并且它比1)自己跟踪会话或2)在浏览器关闭时向服务器发送一些异步JavaScript(不保证发送)。

此链接stardeveloper.com/articles/...已损坏。更新你的答案。
2021-04-16 02:26:55
顺便说一句 - 我不知道我链接到的代码如何在集群/多 VM 环境中工作。我怀疑不是很好。
2021-05-06 02:26:55

我建议您在 Servlet 引擎销毁会话时删除 ID。注册一个HttpSessionListenersessionDestroyed()被调用时删除用户 ID 的

Diodeus的想法只会帮助您更快地检测到会话结束。

在 JavaScript 中,您可以使用该onbeforeclose事件在用户关闭浏览器时将回调传递回服务器。

我通常使用同步 Ajax 调用来执行此操作。

没有万无一失的方法来做你想做的事,但 sblundy 和 Diodeus 都有涵盖大多数情况的计划。如果有人关闭了浏览器中的 Javascript,或者他们的互联网连接出现故障,或者他们的电源断电,您将无能为力。您应该在一段时间不活动后剔除会话(我认为这是 sblundy 建议的侦听会话销毁会做的事情)。

我最近不得不这样做,经过一些搜索,我在网上找到了一些解决方案......所有这些都不能普遍工作!

onbeforeclose 和 onclose 事件用于此任务。但是有两个问题:当用户重新加载页面甚至只是更改当前页面时,它们就会被触发。有一些技巧可以查看事件是否实际上是一个窗口/页面/选项卡关闭(查看一些 Dom 属性在关闭事件时会失控),但是:

  • 它们依赖于浏览器
  • 这些技巧没有记录,因此很脆弱
  • 实际上它们随着浏览器版本/更新而变化......

最糟糕的是,大多数现代浏览器现在都忽略了这些事件,因为它们已被浏览器关闭时弹出窗口的流氓广告滥用。它们不会在 Safari、Opera、IE7 等中被触发。

正如所指出的,大多数具有登录名的 Web 应用程序会在一段时间后破坏用户会话,例如。半小时。我被要求在浏览器关闭时注销以更快地释放宝贵的资源:许可证。因为用户经常忘记注销...

我给出的解决方案是定期(例如 1 分钟)使用 Ajax 请求(发送用户 ID)ping 服务器。如果服务器在 3 分钟内没有收到 ping,它就会断开用户的连接。

你在开玩笑吧?HttpSessionListener 是一个接口,它不提供 Ajax 或魔法。
2021-04-24 02:26:55
这在功能上与使用 HttpSessionListener 几乎相同,只是您必须自己编写 Ajax 和服务器端处理程序,重新发明轮子。
2021-04-29 02:26:55