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)