Push in Vaadin 7 app(“@Push”)的最小例子

我想看看在Vaadin 7中使用新Push技术的最小例子,例如新的@Push注释。

我在使用服务器推送在我的应用程序中工作时遇到问题。 在尝试修复自己的应用之前,我想尝试一个简单的示例应用。

Vaadin书中例子的简化

Vaadin书中有一章关于Push,包括使用Vaadin Charts的例子。

以下是我的代码。 虽然基于上面提到的Vaadin Charts示例,我通过将Chart对象替换为简单的Label对象来简化它。 标签每秒更新一次,以告诉您当前时间。

示例Vaadin应用程序的屏幕截图,以UTC格式显示当前时间

仅供使用示例 – 在实际项目中使用Executor

警告:我的下面的例子是为了简单而构建的, 不是作为生产代码 。 睡眠线程是管理预定线程工作的粗略而笨拙的方式。 Java为这种工作提供了Executor工具。 在一个真实世界的项目中,我会使用ScheduledExecutorService而不是一个睡眠的Thread对象来安排我们的任务(告诉时间)。 相关提示:切勿在Servlet环境中使用Timer 。 有关更全面和更真实的示例,请参阅我对与Vaadin推送类似问题的回答 。

我在这个例子中采用了其他快捷方式,例如:我将Label小部件直接放在UI上,而实际工作则使用Layout来包含Label

我的配置

我的代码在NetBeans 8.0.2中使用Vaadin 7.3.7和Java 8 Update 25,在Mac OS X 10.8.5(Mountain Lion)上使用Tomcat 8.0.15。

推送技术相对较新,尤其是WebSocket的多样性。 请务必使用最新版本的Web服务器,例如Tomcat 7或8的最新更新。

如何使用此示例

此代码是单个文件,即MyUI.java文件。 要使用此代码:

  1. 在您选择的IDE中创建一个新的默认Vaadin应用程序。
  2. 在修改之前,让该示例成功运行。
  3. 用下面的代码替换MyUI类的内容。

@Push Annotation

除了中间的代码,请注意我们如何将@Push批注添加到MyUI类定义中。

示例代码

 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(); } } } } 

这是一个简单但完整的Vaadin 8示例,演示了如何使用服务器推送和Java EE消息传递API,使用Vaadin文档中描述的Broadcaster模式在不同的UI之间发送消息。 如果您对其他用户的消息传递或广播不感兴趣,请仅查看ReceiveMessageUI 。

原则上,这一切归结为以下几点:

  1. 使用@Push注释Vaadin UI以启用服务器推送(默认情况下通过WebSocket连接)
  2. 从其他线程访问UI时,使用access()包装UI更新,默认情况下会自动发送更新:

     getUI().access(() -> layout.addComponent(new Label("Hello!"))); 
  3. 使用Broadcaster模式将消息发布给其他用户并订阅其消息。