The Vaadin Wiki is temporarily in read only mode due to large recent spam attacks.

Enabling server push

Tags: vaadin 7.1.0
WARNING: This wiki page was last edited over a year ago and might be outdated.

The traditional way of communication between client and server in Vaadin has been through XHR, i.e. AJAX requests. The client does a request to the server with information about RPC method invocations, which are executed on the server. As a result the state of one or several components is updated and the changes are sent back as a response to the client. Vaadin 7.1 introduces a new way of doing communications using server push, which enables the server to push state changes to the client without a request initiated by the client.

To create a push enabled application you start by creating a normal Vaadin 7 project using Eclipse or Maven. First you need to add the vaadin-push package to your project, so open pom.xml or ivy.xml and add a vaadin-push dependency, e.g. in Ivy

<dependency org="com.vaadin" name="vaadin-push" rev="&vaadin.version;" conf="default->default" />

and in Maven

<dependency>
	<groupId>com.vaadin</groupId>
	<artifactId>vaadin-push</artifactId>
	<version>${vaadin.version}</version>
</dependency>

Open your UI class and add a @Push annotation to enable push for the ui

#!java
@Push
public class PushTestUI extends UI {

If you are using a servlet 3.0 compatible server, open web.xml and enable asynchronous processing by adding a <async-supported>true</async-supported> tag.

Your servlet definition should look something like this:

	<servlet>
		<servlet-name>MyServlet</servlet-name>
		<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
		<init-param>
			<param-name>ui</param-name>
			<param-value>org.vaadin.example.MyUI</param-value>
		</init-param>
		<async-supported>true</async-supported>
	</servlet>

Your application is now setup for push and will automatically push changes to the browser when needed. You can test it out using e.g. the following UI which only adds a Label and starts a thread which does the real initialization:

#!java

@Push
public class PushTestUI extends UI {

    private VerticalLayout mainLayout;

    @Override
    protected void init(VaadinRequest request) {
        mainLayout = new VerticalLayout();
        mainLayout.setSizeFull();
        mainLayout.setMargin(true);
        setContent(mainLayout);

        mainLayout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
        Label loadingText = new Label("Loading UI, please wait...");
        loadingText.setSizeUndefined();
        mainLayout.addComponent(loadingText);
        new InitializerThread().start();
    }

    class InitializerThread extends Thread {
        @Override
        public void run() {
            // Do initialization which takes some time.
            // Here represented by a 1s sleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }

            // Init done, update the UI after doing locking
            access(new Runnable() {
                @Override
                public void run() {
                    // Here the UI is locked and can be updated
                    mainLayout.removeAllComponents();
                    mainLayout
                            .addComponent(new TextArea("This is the real UI"));
                }
            });
        }
    }
}

The InitializerThread is a Thread which simulates some work using a sleep and then updates the UI with the real content. The UI update takes place inside an access call, which ensures the UI (actually the VaadinSession) is locked to prevent synchronizations problems.

Now deploy the application to your server and open the UI in a browser. You will see the "Loading..." text for roughly a second and the, when the "initialization" is complete, the Label will be replaced by a TextArea.

The changes were automatically pushed to the browser when the access-block was done running. If you want full control on when changes are pushed to the client, add @Push(PushMode.MANUAL) instead and call UI.push() to push the changes (UI.push() needs to be called when the session is locked, so run that inside the access block too).

You can also configure push mode for the whole application using the "pushmode" servlet init parameter. Possible values are automatic,manual and disabled.

It is also possible to switch the push mode on the fly using UI.getPushConfiguration().setPushMode().

0 Attachments
44672 Views
Average (2 Votes)
Comments
Will you give support to Touchkit Addom? I try to use push in a Touchkit Sample project, but i did not be able to run it emoticon
Posted on 4/15/13 7:57 AM.
Push should work in all our supported devices, including iOS and Android. If you have a reproducible issue, please create a ticket
Posted on 4/15/13 11:39 AM in reply to Carlos Salinas Gancedo.
Posted on 4/15/13 12:00 PM.
Finally a resolved my problem and now it works, thanks. I have an example communication a Vaadin Desktop with Vaadin Mobile, Touchkit, using message through Mqtt protocol (Eclipse Paho Implementation). I would be interested in shared my experience in a blog post. Could i do it?
Posted on 4/15/13 5:18 PM in reply to Artur Signell.
Couple of corrections:

Please document @Push - it would most probably be the default way of enabling push. Also mention dynamic switching of push.

Change runSafely to access
Posted on 5/2/13 1:25 PM.
Sounds good. Just blog about it and send a link to your blog to joonas@vaadin.com.
Posted on 5/6/13 2:23 PM in reply to Carlos Salinas Gancedo.
If I add a custom widgetset to the demo app the push is not working any more, the changes are not propagated, has anyone experimented this issue?
Posted on 5/30/13 1:44 PM.
Hello,
I added the dependency, but when I added the <async-supported> property to servlet.xml
I get the following error :: Any help please..!!

cvc-complex-type.2.4.a: Invalid content was found starting with element 'async-supported'. One of
'{"http://java.sun.com/xml/ns/javaee":init-param, "http://java.sun.com/xml/ns/javaee":load-on-startup,
"http://java.sun.com/xml/ns/javaee":run-as, "http://java.sun.com/xml/ns/javaee":security-role-ref}' is
expected.
Posted on 8/19/13 5:35 PM.
ok resolved it... had to change the servlet version from 2.5 to 3.0
Posted on 8/19/13 5:41 PM in reply to Panshul Gupta.
Is it possible to push to all users at once instead of the above example? Our app is scaling up and might have 100's of users online (many more in the future).
Posted on 10/10/13 1:46 PM.
Never mind. Reading the docs now.
Posted on 10/10/13 1:51 PM in reply to Martin Phee.
How can this be used in a portlet instead of an application?

<async-supported>true</async-supported>
is invalid in <portlet>
Posted on 7/8/14 10:37 AM.
The example above does not work with Vaadin 7.2.4 in eclipse. The new textArea is never showing.

@Push
@SuppressWarnings("serial")
@Theme("testpush724")
public class Testpush724UI extends UI
{
private VerticalLayout mainLayout;

@WebServlet(value = "/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = Testpush724UI.class)
public static class Servlet extends VaadinServlet
{
}

@Override
protected void init(VaadinRequest request)
{
mainLayout = new VerticalLayout();
mainLayout.setSizeFull();
mainLayout.setMargin(true);
setContent(mainLayout);

mainLayout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
Label loadingText = new Label("Loading UI, please wait...");
loadingText.setSizeUndefined();
mainLayout.addComponent(loadingText);
new InitializerThread().start();
}

class InitializerThread extends Thread
{
@Override
public void run()
{
// Do initialization which takes some time.
// Here represented by a 1s sleep
try
{
Thread.sleep(1000);

// Init done, update the UI after doing locking
access(new Runnable()
{
@Override
public void run()
{
// Here the UI is locked and can be updated
mainLayout.removeAllComponents();
mainLayout.addComponent(new TextArea("This is the real UI"));
}
});
}
catch (InterruptedException e)
{
e.printStackTrace();
}


}
}

}
Posted on 7/15/14 3:23 PM in reply to Anky S..
Just a hint:

I had a couple problems when using WebSockets. In the end I found out that it was my antivirus software. After switching it off, everything worked fine.
Posted on 7/21/14 3:04 PM in reply to Jean-Christophe Fortier.
I tried it with Tomcat 8.0.9 and Vaadin 7.2.6 and it's working now.
Posted on 8/2/14 4:56 PM in reply to Nico Przybylek.
i can't set <async-supported>true</async-supported> property in side <servlet> tag.
any idea?.
Posted on 10/6/14 6:13 AM.
When I put the @Push annotation into my UI class, calls to web services never seem to complete. They just hang out there. I am not calling them from the new thread. The only changes I made was to add the annotation to the UI class. Is there something special I need to do so that they will complete?
Posted on 4/10/15 4:28 PM.
@Jean-Christophe: Do you think it was related to tomcat or vaadin version? I am having same situation like you (tomcat 7, vaadin 7.5.10).
Posted on 12/20/15 9:04 PM in reply to Jean-Christophe Fortier.
@Jean-Christophe: Do you think it was related to tomcat or vaadin version? I am having same situation like you (tomcat 7.0.61, vaadin 7.5.10) - both latest of their kind. Therefore I'm wondering, why it does not work. No error message, no warning. The demo has just no effect.
Posted on 12/20/15 9:06 PM in reply to Jean-Christophe Fortier.
Just for the record, there are so many examples where the servlet is configured either in xml or by annotation on a servlet subclass in code, but for this to work I did only need to use the @Push annotation (and I also use @CDIUI("my-app"), maybe the VaadinCDIServlet is asynch by default?). In my UI subclass I only @Inject a component, where the thread class is declared. The thread is started in a @PostConstruct method. Because the component does inherit from a layout and not UI, I use getUI().access(... in the thread.
Posted on 2/10/16 1:57 AM.