Using Server-Push in a Vaadin app

Just a short post to show how easy it is with Vaadin 7 to use server push in an application.

When doing some tasks in a background thread in a Vaadin application, there probably will come the time when some data needs to be shown in the UI. But as these data changes come from background processing, there is no direct possibility to show them in the UI, as UI changes normally are only reflected after a communication roundtrip from client to server to client which happens as a reaction to some user interaction. So even if you update your UI components in a UI.access() call – which is needed for correct access from the worker thread – these changes will not show in the UI until the next click. This is not what the user wants.

As a solution for this, Vaadin offers server push, the following shows how to implement it. I am using a Vaadin-Spring-Boot project to create the basis setup. The UI just contains a label which will be constantly updated from a background thread with the current time.

The pom is modified to include the following dependency:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-push</artifactId>
    <version>7.4.5</version>
</dependency>

Then the UI class is in addition to the @SpringUI annotation decorated with @Push.
The consequence of this is, that the framework after every call to access() will use a server push mechanism to update the UI in the browser.

/**
 * Copyright (c) 2015 sothawo
 *
 * 
 */
package demo;

import com.vaadin.annotations.Push;
import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ForkJoinPool;

/**
 * UI class.
 *
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Theme("valo")
@SpringUI
@Push
public class DemoUI extends UI {
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        layout.setSpacing(true);

        final Label labelTime = new Label("???");
        layout.addComponent(labelTime);

        // now in a background thread we constantly update the time
        final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        ForkJoinPool.commonPool().submit(() -> {
            boolean keepGoing = true;
            while (keepGoing) {
                access(() -> labelTime.setValue(LocalTime.now().format(dateTimeFormatter)));
                try {
                    Thread.sleep(600);
                } catch (InterruptedException e) {
                    keepGoing = false;
                }
            }
        });

        setContent(layout);
    }
}

And this makes the browser happily display the always current time:

push-time