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.
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.
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 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.
This code is a single file, the MyUI.java
file. To use this code:
MyUI
class with the code below.@Push
AnnotationBeside the code in the middle, note how we added the @Push
annotation to the MyUI
class definition.
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();
}
}
}
}