Asynchronous Updates
This section describes to use server push from your application code. See Server Push Configuration for an overall description on what server push means and how to configure your application to use server push.
Making changes to a UI from another thread and pushing them to the browser requires locking the user session. Otherwise, the UI update done from another thread could conflict with a regular event-driven update and cause either data corruption or deadlocks. Because of this, you may only access an UI using the access()
method, which locks the session to prevent conflicts. It takes as parameter a Command
to execute while the session is locked.
For example:
Java
ui.access(new Command() {
@Override
public void execute() {
statusLabel.setText(statusText);
}
});
You also use a simple lambda expression to define your access command.
Java
ui.access(() -> statusLabel.setText(statusText));
If the push mode is manual
, you need to push the pending UI changes to the browser explicitly with the push()
method.
Java
ui.access(() -> {
statusLabel.setText(statusText);
ui.push();
});
Below is a complete example of a case where we make UI changes from another thread.
Java
@Push
@Route("push")
public class PushyView extends VerticalLayout {
private FeederThread thread;
@Override
protected void onAttach(AttachEvent attachEvent) {
add(new Span("Waiting for updates"));
// Start the data feed thread
thread = new FeederThread(attachEvent.getUI(), this);
thread.start();
}
@Override
protected void onDetach(DetachEvent detachEvent) {
// Cleanup
thread.interrupt();
thread = null;
}
private static class FeederThread extends Thread {
private final UI ui;
private final PushyView view;
private int count = 0;
public FeederThread(UI ui, PushyView view) {
this.ui = ui;
this.view = view;
}
@Override
public void run() {
try {
// Update the data for a while
while (count < 10) {
// Sleep to emulate background work
Thread.sleep(500);
String message = "This is update " + count++;
ui.access(() -> view.add(new Span(message)));
}
// Inform that we are done
ui.access(() -> {
view.add(new Span("Done updating"));
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
When sharing data between UIs or user sessions, you need to consider the message-passing mechanism more carefully, as explained in Creating Collaborative Views.