Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vaadin session setMaxInactiveInterval UI response inconsistant

I have set the max inactive interval for Vaadin session as following.

VaadinSession.getCurrent().getSession().setMaxInactiveInterval(60); 

Added a session destroy listener as following for testing.

    servletService.addSessionDestroyListener(new SessionDestroyListener() {
    public void sessionDestroy(SessionDestroyEvent event) {
        System.out.println("SESSION TIMEOUT");
    }
});

This listener get called at the desired time on the server side. However I cannot see "Session Expired" message on the browser side at the same time. Normally it gets displayed between 4th and 5th minutes. Is there a way to get both of these at the same time in a consistent manner.

Also note that we are not using push and it is not an option for us at the moment.

Doing client side polling will reset last active time of the sessions and can keep the session active forever if poll interval is lesser than maxInactiveInterval.

like image 711
Don Srinath Avatar asked Sep 01 '15 05:09

Don Srinath


3 Answers

Vaadin application keeps Client Side and Server Side communication during session life-cycle. There is parameter calls heartbeatInterval with default value 5 mins (300s). So it is means that every 5 mins Client Side ask Server if session still alive. That is why, when Session is destroyed you see message in Console and only after some period of time you see Session Expired message in a Browser.

You can change heartbeatInterval property and set smaller value (in seconds), but remember that you need to set closeIdleSessions=true explicitly as well. In example below I set this value to 1 second.

@VaadinServletConfiguration(heartbeatInterval=1, closeIdleSessions=true, productionMode = false, ui = MyUI.class)
    public static class Servlet extends VaadinServlet {
    }
like image 105
Taras Klym Avatar answered Nov 04 '22 21:11

Taras Klym


The problem :

Your session is invalidated on the server side, everything is good. But the problem is that your client is never notified of this event. You have to do an interaction with the server to get a Session Expired message, like pressing the button, refreshing the page, etc...

How to fix this?

To fix this, you have some solutions:

  • Use @Push annotation see Documentation
  • Force client-side refresh using getPage().reload()
  • Change nothing and your session timeout will appear on next Client-Side action
  • Implement a "Session lookup" on client side to watch every X seconds if the session is still valid, if it is expired, simply call Page.getCurrent.reload() from client side.

Be careful with @Push

Depending on the application server you are Using, you may need to update it to support @Push (I had to with tomcat7, because tomcat7 doesn't support WebSocket)

like image 38
Supamiu Avatar answered Nov 04 '22 21:11

Supamiu


Following solution worked for me in this scenario of not having @Push enabled as well as without any custom js widgets. First set maxInactiveInterval as following in the main class. Showing only the code related to this solution.

    public class MyApplication extends UI { 
      @Override
        protected void init(VaadinRequest request) {
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(sessionTimeout);
    }

    }

We have to default session expired message as following. This has been suggested in a Vaadin forum as a solution and it said it should work within 15 seconds of session timeout.

    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
}

Then in the web.xml added high heartbeat interval which will be higher than the maxInactiveInterval.

<context-param>
    <param-name>heartbeatInterval</param-name>
    <param-value>1200</param-value>
</context-param>
like image 1
Don Srinath Avatar answered Nov 04 '22 21:11

Don Srinath