2008-11-18 3 views
16

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

ответ

13

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

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

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

+0

BTW - я понятия не имею, как код, который я связан с будет работать в кластерном/многопользовательской среде VM. Я подозреваю, что не очень хорошо. –

+0

Эта ссылка http://www.stardeveloper.com/articles/display.html?article=2001112001&page=1 не работает. Обновите ur ответ. – OO7

3

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

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

+0

Нет, увидеть мой ответ ... – PhiLho

7

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

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

2

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

2

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

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

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

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

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

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

+0

Это практически функционально то же самое, что и использование HttpSessionListener, за исключением того, что вам нужно было самостоятельно обработать обработчик Ajax и серверной стороны, повторно изобретая колесо. –

+0

Вы шутите, не так ли? HttpSessionListener - это интерфейс, он не обеспечивает Ajax и магию. – PhiLho

0

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

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

Ну, на самом деле это не означает, что браузер закрыт, он просто обнаруживает, что кто-то возвращается на ваш сервер с одного и того же клиента без ваших включенных заголовков, поэтому он отправляет их обратно на страницу входа. Таким образом, это не действительно достойный ответ. – rjdamore

Смежные вопросы