Minimal example of Push in Vaadin 7 app ("@Push")
Asked Answered
M

2

15

I want to see the most minimal example of using the new Push technology in Vaadin 7, such as the new @Push annotation.

I am having problems getting server-push to work in my app. I would like to try a simple example app before trying to fix my own app.

Mckinley answered 6/1, 2015 at 22:37 Comment(3)
Dear Down-Voter: Please leave a criticism along with your vote.Mckinley
After studying this page, you may find this page useful: Displaying Same Data Aross Multiple Clients Using Push in Vaadin 7 appMckinley
For a full working example of asynchronously updating a widget in the UI using Push in Vaadin 8, see my Answer on the Question, Vaadin: Update UI after data returnedMckinley
M
24

Simplification Of Example In The Book Of Vaadin

The Book Of Vaadin includes a chapter on Push, including an example using Vaadin Charts.

Below is my code. While based on that Vaadin Charts example mentioned above, I simplified it by replacing the use of a Chart object with a simple Label object. The Label updates every second or so to tell you the current time.

screen shot of example Vaadin app telling current time in UTC as text

For Example Use Only – Use an Executor in real-world project

Caveat: My example below is built for simplicity, not intended as production code. Sleeping a thread is a crude and awkward way to manage scheduled threaded work. Java provides the Executor facility for this kind of work. In a real-world project I would use a ScheduledExecutorService rather than a single sleeping Thread object to schedule our task (of telling time). Related tip: Never use a Timer in a Servlet environment. For a fuller and more real-world example, see my Answer to a similar Question about Push with Vaadin.

I took other shortcuts in this example, such as: I place the Label widget directly on the UI whereas real-world work would use a Layout to contain the Label.

My Configuration

My code is using Vaadin 7.3.7 with Java 8 Update 25 in NetBeans 8.0.2 and Tomcat 8.0.15 on Mac OS X 10.8.5 (Mountain Lion).

Push technology is relatively new, especially the WebSocket variety. Be sure to use recent versions of your web server, such as recent updates to Tomcat 7 or 8.

How To Use This Example

This code is a single file, the MyUI.java file. To use this code:

  1. Create a new default Vaadin app in your IDE of choice.
  2. Get that example running successfully, before modifying.
  3. Replace the contents of MyUI class with the code below.

@Push Annotation

Beside the code in the middle, note how we added the @Push annotation to the MyUI class definition.

Example Code

package com.example.pushvaadinapp;

import com.vaadin.annotations.Push;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import javax.servlet.annotation.WebServlet;

/**
 * © 2014 Basil Bourque. This source code may be used freely forever by anyone absolving me of any and all responsibility.
 *
 *  +----------------------------+
 *  |  NOT FOR PRODUCTION USE!   |
 *  +----------------------------+
 *     Sleeping threads is an awkward way to manage scheduled background work.
 *     By the way, never use a 'Timer' in a Servlet environment. 
 *     Use an Executor instead, probably a ScheduledExecutorService.
 */
@Push
@Theme ( "mytheme" )
@Widgetset ( "com.example.pushvaadinapp.MyAppWidgetset" )
public class MyUI extends UI
{

    Label label = new Label( "Now : " );

    @Override
    protected void init ( VaadinRequest vaadinRequest )
    {
        // Put a widget on this UI. In real work we would use a Layout.
        setContent( this.label );

        // Start the data feed thread
        new FeederThread().start();
    }

    @WebServlet ( urlPatterns = "/*" , name = "MyUIServlet" , asyncSupported = true )
    @VaadinServletConfiguration ( ui = MyUI.class , productionMode = false )
    public static class MyUIServlet extends VaadinServlet
    {
    }

    public void tellTime ()
    {
        label.setValue( "Now : " + new java.util.Date() ); // If Java 8, use: Instant.now(). Or, in Joda-Time: DateTime.now().
    }

    class FeederThread extends Thread
    {

        int count = 0;

        @Override
        public void run ()
        {
            try {
                // Update the data for a while
                while ( count < 100 ) {
                    Thread.sleep( 1000 );

                    // Calling special 'access' method on UI object, for inter-thread communication.
                    access( new Runnable()
                    {
                        @Override
                        public void run ()
                        {
                            count ++;
                            tellTime();
                        }
                    } );
                }

                // Inform that we have stopped running
                // Calling special 'access' method on UI object, for inter-thread communication.
                access( new Runnable()
                {
                    @Override
                    public void run ()
                    {
                        label.setValue( "Done." );
                    }
                } );
            } catch ( InterruptedException e ) {
                e.printStackTrace();
            }
        }
    }
}
Mckinley answered 6/1, 2015 at 22:37 Comment(3)
is the widgetset needed? my guess: no. also why bother with (and explain for a whole paragraph) java.time, when the goal is to have a minimal working example? just use a counter or new Date().toString(). and in your question you state, that you wanted to have a simple test app where you can test this stuff. so why not put your whole project (including your pom/gradle/younameit) on github for the SO users, that find your question?Aldershot
@Aldershot All good points; Thank you. [A] I killed the java.time use and discussion as you suggested. [B] As for the widgetset, that annotation is the default in the new multi-module project created by the new Maven archetype, as delivered by the 1.1.3 update to the Vaadin Plugin For NetBeans. Furthermore, the vague doc implies the widgetset (and theme) is now automatically optimized in the production module’s compilation. So I'll leave that in place.Mckinley
Why can't you use a Timer in a Servlet environment?Veteran
D
1

Here is a simple but full Vaadin 8 example that demonstrates how to use server push and Java EE messaging APIs to send messages between different UIs using the Broadcaster pattern described in Vaadin docs. If you are not interested in messaging or broadcasting to other users, then look at ReceiveMessageUI only.

In principle it all boils down to the following:

  1. Annotate the Vaadin UI with @Push to enable server push (by default over a WebSocket connection)
  2. Wrap UI updates with access() when accessing it from other threads, sending updates happens automatically by default:

    getUI().access(() -> layout.addComponent(new Label("Hello!")));
    
  3. Use the Broadcaster pattern to publish messages to other users and to subscribe to their messages.

Dieselelectric answered 12/3, 2017 at 17:12 Comment(3)
By “Broadcaster pattern” do you mean the Observer pattern or something else?Mckinley
Something else, I mean the Broadcaster pattern documented in Vaadin docs.Dieselelectric
Better to look for exa,ple in docs vaadin.com/docs/v8/framework/advanced/advanced-push.htmlVeteran

© 2022 - 2024 — McMap. All rights reserved.