Как обнаружить закрытие браузера? - PullRequest
16 голосов
/ 18 ноября 2008

В моем веб-приложении, когда пользователь входит в систему, я добавляю его Id к вектору действительных идентификаторов в сервлете, когда он выходит из системы, я удаляю его Id из вектора, чтобы видеть, сколько текущих пользователей активный, если пользователь забывает выйти, мой сгенерированный сервлетом 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 ]
...

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

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

Ответы [ 6 ]

13 голосов
/ 18 ноября 2008

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

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

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

7 голосов
/ 18 ноября 2008

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

Идея

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

3 голосов
/ 18 ноября 2008

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

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

2 голосов
/ 19 ноября 2008

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

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

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

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

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

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

2 голосов
/ 18 ноября 2008

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

0 голосов
/ 12 апреля 2013

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

Добавление дополнительных заголовков в ответ 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...