Как обнаружить закрытие браузера?

В моем веб-приложении, когда пользователь входит в систему, я добавляю его идентификатор к вектору допустимых идентификаторов в сервлете, когда он выходит из системы, я удаляю его идентификатор из вектора, поэтому я могу видеть, сколько активных пользователей активно, если пользователь забывает выйти из системы, мой сервлет сгенерированный html имеет:

 

в теге, чтобы автоматически вывести его из системы.

Но я заметил, что многие пользователи там навсегда, никогда не выходили из системы. Я узнал, почему, закрыв их браузеры, они никогда не будут вручную или автоматически выходить из системы, поэтому их идентификаторы пользователя никогда не будут удалены из допустимого вектора идентификаторов пользователя.

Итак, мой вопрос: как определить, как пользователи закрывают свои браузеры, поэтому мой сервлет может удалить свои идентификаторы из вектора?


Я вижу некоторый свет в конце туннеля, но проблемы все еще есть, моя программа имеет что-то вроде этого:

Список активных пользователей:

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

Как узнать, от слушателя сеанса, сеанс пользователя закончился и, следовательно, удалить его из моего списка?

Я надеялся, что когда сессия закончится, будет вызван метод destroy() HttpServlet, и я могу удалить идентификатор пользователя там, но он никогда не вызывается, когда пользователь закрывает свой браузер, почему? И есть ли какой-либо другой метод в HttpServlet, который вызывается при закрытии сеанса?

На серверной стороне нет возможности узнать (если вы не используете какой-либо JavaScript для отправки сообщения на сервер), который был закрыт браузером. Как может быть? Подумайте, как работает HTTP – все это запрос и ответ.

Однако сервер приложений будет отслеживать, когда сеансы активны, и даже скажет вам, когда сеанс был уничтожен (например, из-за тайм-аута). Взгляните на эту страницу, чтобы узнать, как настроить HttpSessionListener для получения этих событий. Затем вы можете просто отслеживать количество активных сеансов.

Количество активных сеансов будет отставать от фактического количества текущих пользователей, так как некоторое время (настраиваемое) время должно пройти до истечения времени ожидания сеанса; однако это должно быть несколько близко (вы можете снизить тайм-аут сеанса для повышения точности), и это намного проще и проще, чем 1) отслеживать сеансы самостоятельно или 2) отправлять asynchronous JavaScript на сервер при закрытии браузера ( который не гарантированно отправляется).

Я предлагаю вам удалить идентификатор, когда механизм Servlet уничтожает сеанс. Зарегистрируйте HttpSessionListener который удаляет идентификатор пользователя при sessionDestroyed() .

Идея Diodeus поможет вам обнаружить, что сеанс более чем сразу.

в JavaScript вы можете использовать событие onbeforeclose для передачи вызова на сервер, когда пользователь закрывает браузер.

Обычно я использую синхронный вызов Ajax для этого.

Нет надежного способа сделать то, что вы пытаетесь сделать, но у обоих и у Diodeus есть планы, которые будут охватывать большинство обстоятельств. Вы ничего не можете сделать с тем, кто отключает Javascript в своем браузере, или их интернет-соединение идет вниз, или их мощность отключается. Вы должны просто отбирать сеансы после определенного периода бездействия (что, по моему мнению, будет означать, что предложение sbundy о прослушивании для уничтожения сеанса).

Я должен был сделать это недавно, и после некоторых поисков я нашел некоторые решения в Сети … все они не работают повсеместно!

onbeforeclose и onclose события используются для этой задачи. Но есть два улова: они запускаются, когда пользователь перезагружает страницу или даже просто меняет текущую страницу. Есть трюки, чтобы увидеть, действительно ли событие является закрытием windows / страницы / вкладки (глядя на некоторые свойства дома, идущие на закрытие события), но:

  • Они зависят от браузера
  • Трюки недокументированы, поэтому хрупкие
  • И на самом деле они варьируются в зависимости от версии браузера / обновления …

И что хуже всего, эти события в настоящее время игнорируются большинством современных браузеров, потому что они были злоупотреблены рекламой изгоев, выпадающими из окон при закрытии браузера. Они не запускаются в Safari, Opera, IE7 и т. Д.

Как уже отмечалось, большинство веб-приложений с логином через некоторое время уничтожают сеанс пользователя, например. полчаса. Меня попросили выйти из браузера, чтобы быстрее освободить ценный ресурс: лицензии. Потому что пользователи часто забывают выйти …

Решением, которое я дал, было ping с запросом Ajax (посылкой идентификатора пользователя) сервером с регулярными интервалами (скажем, 1 минута). Если сервер не получает пинг, скажем, 3 минуты, он отключает пользователя.

Вот грязный способ выполнить «обнаружение закрытия браузера». Я нашел это на форуме где-то на этом сайте, когда я снова найду его, я свяжусь с ним.

Добавьте дополнительные заголовки в ответ http. Когда появятся дополнительные запросы, они будут содержать эти дополнительные заголовки. Вы можете проверить эти заголовки, и если они не присутствуют, вы можете убить сеанс, так что начнется новый. Хотя это не «уведомляет» вас, если браузер закрыт, он может сказать вам, закрыл ли кто-то свое окно и пытается вернуться, поскольку заголовки, которые вы добавили, будут отсутствовать.

  wrapper.setHeader("Cache-Control", "no-cache, no-store, must- revalidate"); wrapper.setHeader("Pragma", "no-cache"); wrapper.setDateHeader("Expires", 0); Where wrapper is a response wrapper. if (wrapper.getHeaderNames().size() < the number of headers you are expecting) request.getSession().invalidate(); Not perfect but it might help someone. 
  • Как загрузить файлы на сервер с помощью JSP / Servlet?
  • Регистрация активности пользователя в веб-приложении
  • Легкий способ заполнения Javabeans на основе параметров запроса
  • Как установить JSTL? Абсолютный uri: http://java.sun.com/jstl/core не может быть разрешен
  • Как загрузить ресурс из файла jar, упакованного в военный файл?
  • Как правильно выйти из веб-приложения Java EE 6 после входа в систему
  • Получить параметр, отправленный через jquery ajax в Java Servlet
  • Браузер не может получать / находить относительные ресурсы, такие как CSS, изображения и ссылки при вызове сервлета, который пересылает JSP
  • не удалось найти Factory: javax.faces.context.FacesContextFactory
  • Получить управляемый bean-элемент JSF по имени в любом classе, связанном с Servlet
  • Сервлеты для тестирования модhive
  • Давайте будем гением компьютера.