Vaadin之书包含了一个关于推送的章节,其中包括使用Vaadin Charts的示例。
以下是我的代码。基于上述提到的Vaadin Charts示例,我通过将Chart
对象替换为简单的Label
对象来进行简化。该标签每秒更新一次,以告诉您当前时间。
注意:我下面的示例是为了简单起见而构建的,不适用于生产代码。睡眠线程是管理计划线程工作的一种粗糙和笨拙的方式。Java 提供了 Executor
设施来处理这种工作。在真实项目中,我会使用 ScheduledExecutorService 来安排我们任务(告诉时间),而不是使用单个睡眠的 Thread
对象。相关提示:永远不要在 Servlet 环境中使用 Timer
。有关更完整和更真实的示例,请参见 my Answer 中关于 Vaadin 推送的类似问题。
我在这个示例中采取了其他捷径,例如:将 Label
小部件直接放置在 UI
上,而真实的工作会使用 Layout
来包含 Label
。
我的代码使用Vaadin 7.3.7和Java 8 Update 25在NetBeans 8.0.2和Tomcat 8.0.15上运行,操作系统为Mac OS X 10.8.5(Mountain Lion)。
推送技术相对较新,特别是WebSocket类型。请确保使用最新版本的Web服务器,例如Tomcat 7或8的最新更新。
此代码是一个单一文件,即MyUI.java
文件。要使用此代码:
MyUI
类的内容替换为以下代码。@Push
注解除了中间的代码外,请注意我们如何将@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();
}
}
}
}
new Date().toString()
即可。而且在你的问题中,你提到你想要一个简单的测试应用程序,在这个应用程序中可以测试这些东西。那么为什么不将你的整个项目(包括pom/gradle/等等)放在GitHub上供找到你问题的Stack Overflow用户使用呢? - cfrickproduction
模块的编译现在自动优化了widgetset(和主题)。所以我会保持原样。 - Basil Bourque这里是一个简单但完整的Vaadin 8示例,演示了如何使用服务器推送和Java EE消息API在不同的UI之间发送消息,使用Broadcaster模式,该模式在Vaadin文档中有描述。如果您对消息传递或向其他用户广播不感兴趣,则仅查看ReceiveMessageUI。
原则上,所有问题都可以归结为以下内容:
@Push
to enable server push (by default over a WebSocket connection)Wrap UI updates with access()
when accessing it from other threads, sending updates happens automatically by default:
getUI().access(() -> layout.addComponent(new Label("Hello!")));
Use the Broadcaster pattern to publish messages to other users and to subscribe to their messages.