Подтвердить что ты не робот

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

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

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

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

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

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


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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

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

Ответ 6

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

Добавьте дополнительные заголовки в ответ 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.