Vaadin session setMaxInactiveInterval UI ответ непоследователен
Я установил максимальный неактивный интервал для сеанса Vaadin следующим образом.
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(60);
Добавлен сеанс уничтожить прослушиватель следующим образом для тестирования.
servletService.addSessionDestroyListener(new SessionDestroyListener() {
public void sessionDestroy(SessionDestroyEvent event) {
System.out.println("SESSION TIMEOUT");
}
});
Этот прослушиватель вызывается в нужное время на стороне сервера.
Однако я не вижу сообщение "Session Expired" на стороне браузера одновременно. Обычно он отображается между 4 и 5 минутами.
Есть ли способ получить оба из них в одно и то же время согласованным образом.
Также обратите внимание, что мы не используем push, и на данный момент это не вариант для нас.
Выполнение опроса на стороне клиента будет reset последним активным временем сеансов и может поддерживать сеанс активным навсегда, если интервал опроса меньше maxInactiveInterval.
Ответы
Ответ 1
Следующее решение сработало для меня в этом сценарии отсутствия поддержки @Push, а также без каких-либо пользовательских js-виджета.
Сначала установите maxInactiveInterval следующим образом в основном классе. Отображение только кода, связанного с этим решением.
public class MyApplication extends UI {
@Override
protected void init(VaadinRequest request) {
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(sessionTimeout);
}
}
У нас есть сообщение об окончании сеанса по умолчанию, как указано ниже. Это было предложено на форуме Vaadin в качестве решения, и он сказал, что он должен работать в течение 15 секунд после таймаута сеанса.
public class CustomInitServlet extends VaadinServlet {
getService().setSystemMessagesProvider(
new SystemMessagesProvider() {
@Override
public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
CustomizedSystemMessages customizedSystemMessages = new CustomizedSystemMessages();
customizedSystemMessages.setSessionExpiredMessage(null);
customizedSystemMessages.setSessionExpiredCaption(null);
customizedSystemMessages.setSessionExpiredNotificationEnabled(true);
return customizedSystemMessages;
}
});
// other code
}
Затем в web.xml добавлен высокий интервал сердцебиения, который будет больше, чем maxInactiveInterval.
<context-param>
<param-name>heartbeatInterval</param-name>
<param-value>1200</param-value>
</context-param>
Ответ 2
Приложение Vaadin поддерживает связь на стороне клиента и на стороне сервера в течение жизненного цикла сеанса. Существует параметр heartbeatInterval со значением по умолчанию 5 минут (300 с). Таким образом, это означает, что каждые 5 минут клиентская сторона запрашивает сервер, если сеанс еще жив. Вот почему, когда сеанс уничтожен, вы видите сообщение в консоли и только через некоторое время вы видите сообщение Session Expired в браузере.
Вы можете изменить свойство heartbeatInterval и установить меньшее значение (в секундах), но помните, что вам нужно также явно установить closeIdleSessions = true. В приведенном ниже примере я устанавливаю это значение в 1 секунду.
@VaadinServletConfiguration(heartbeatInterval=1, closeIdleSessions=true, productionMode = false, ui = MyUI.class)
public static class Servlet extends VaadinServlet {
}
Ответ 3
Проблема:
Ваша сессия недействительна на стороне сервера, все хорошо. Но проблема в том, что ваш клиент никогда не уведомляется об этом событии. Вам необходимо выполнить взаимодействие с сервером, чтобы получить сообщение с истекшим сроком действия, например, нажать кнопку, обновить страницу и т.д.
Как это исправить?
Чтобы исправить это, у вас есть несколько решений:
- Использовать аннотацию @Push см. Документацию
- Настроить обновление на стороне клиента с помощью getPage(). reload()
- Ничего не измените, и ваш тайм-аут сеанса появится при следующем действии на стороне клиента
- Реализовать "сеансовый поиск" на клиентской стороне, чтобы смотреть каждые X секунд, если сеанс по-прежнему действителен, если он истек, просто вызовите страницу .getCurrent.reload() со стороны клиента.
Будьте осторожны с @Push
В зависимости от используемого сервера приложений вам может потребоваться обновить его для поддержки @Push (я должен был с tomcat7, потому что tomcat7 не поддерживает WebSocket)