Hendrik Ebbers
Hendrik Ebbers

Reputation: 2600

UI / VaadinSession timeout

I'm using Vaadin Flow 13 together with Spring Boot. In my 'application.properties' I have specified the following values:

vaadin.servlet.heartbeatInterval=5
vaadin.servlet.productionMode=true
vaadin.servlet.closeIdleSessions=true

I do not have a web.xml or overwritten the Vaadin Servlet (like described here).

In my application I have a view that registers on a Hazelcast event bus in the onAttach method. I use ui.access / push to sync Hazelcast with the Vaadin lifecycle and it looks like it is working fine. In the onDetach method the listener to Hazelcast is removed. When I now navigate to a different view the listener is removed correctly.

But if I press the refresh button in the browser while my view is open the onDetach method is not called and a new UI is created. I totally understand that workflow and assumed that I need to take care of the UI / UI-Session timeout to remove the listener. Sadly I have no idea where I can attach a listener to trigger the deregistration of my Hazelcast listener.

I created the following view to debug the lifecycle:

@Route(layout = ConcreteAppLayout.class)
public class MainView extends VerticalLayout {

    private static final AtomicLong counter = new AtomicLong(0);

    protected MainView() {
        setId("main-view-" + counter.incrementAndGet());
        setAlignItems(Alignment.CENTER);
        add(new Label("MainView"));

        print("A new MainView(" + getId() + ") is created");
    }

    @Override
    protected void onAttach(final AttachEvent attachEvent) {
        final Optional<VaadinService> service = getUI()
                 .map(ui -> ui.getSession())
                 .map(s -> s.getService());

        getUI().ifPresent(ui -> ui.addDetachListener(e -> print("UI of MainView(" + getId() + ") destroyed")));
        service.ifPresent(s -> s.addSessionDestroyListener(e -> print("Session of MainView(" + getId() + ") destroyed")));

        System.out.println("MainView(" + getId() + ") is attached");
    }

    @Override
    protected void onDetach(final DetachEvent detachEvent) {
        print("MainView(" + getId() + ") is detached");
    }

    private void print(final String s) {
        System.out.println(s);
    }
}

If I open the view and press refresh I receive more or less the following log:

MainView(1) is created
MainView(1) is attached

REFRESH OF BROWSER

MainView(2) is created
MainView(2) is attached

If I now navigate to a different view I receive

MainView(2) is detached

MainView(1) or its UI is never closed. How can I handle that problem?

Upvotes: 2

Views: 862

Answers (1)

Hendrik Ebbers
Hendrik Ebbers

Reputation: 2600

My problem was the vaadin.servlet.heartbeatInterval property in the application.properties. Looks like the correct name is vaadin.heartbeatInterval. After changing the property name everything works as expected.

Upvotes: 4

Related Questions