我想看看在 Vaadin 7 中使用新的Push 技术的最简单的例子,比如新的@Push
注解。
我在让服务器推送在我的应用程序中工作时遇到问题。在尝试修复我自己的应用程序之前,我想尝试一个简单的示例应用程序。
The Book Of Vaadin包括一章关于 Push 的章节,其中包括一个使用Vaadin 图表的示例。
下面是我的代码。虽然基于上面提到的 Vaadin 图表示例,但我通过将对象的使用替换为Chart
简单Label
对象来简化它。标签每秒钟左右更新一次,以告诉您当前时间。
警告:我下面的示例是为简单起见而构建的,而不是作为生产代码。休眠线程是管理计划线程工作的一种粗略且笨拙的方式。JavaExecutor
为这种工作提供了便利。在现实世界的项目中,我会使用ScheduledExecutorService而不是单个睡眠Thread
对象来安排我们的任务(告诉时间)。相关提示:切勿Timer
在 Servlet 环境中使用 a。有关更完整和更真实的示例,请参阅我对有关使用 Vaadin 推送的类似问题的回答。
在此示例中我采用了其他快捷方式,例如:我将Label
小部件直接放在 上,UI
而实际工作将使用 aLayout
来包含Label
.
我的代码在 NetBeans 8.0.2 和 Mac OS X 10.8.5(Mountain Lion)上使用带有 Java 8 Update 25 的 Vaadin 7.3.7 和 Tomcat 8.0.15。
推送技术相对较新,尤其是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();
}
}
}
}
这是一个简单但完整的 Vaadin 8 示例,它演示了如何使用服务器推送和 Java EE 消息传递 API 来使用Vaadin 文档中描述的广播模式在不同的 UI 之间发送消息。如果您对向其他用户发送消息或广播不感兴趣,请仅查看ReceiveMessageUI。
原则上,这一切都归结为以下几点:
@Push
以启用服务器推送(默认通过 WebSocket 连接)当从其他线程访问 UI 更新时包装 UI 更新,access()
默认情况下会自动发送更新:
getUI().access(() -> layout.addComponent(new Label("Hello!")));
使用广播者模式向其他用户发布消息并订阅他们的消息。