Vaadin 7 应用程序中推送的最小示例(“@Push”)

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

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

我在让 server-push 在我的应用程序中工作时遇到问题。在尝试修复我自己的应用程序之前,我想尝试一个简单的示例应用程序。

Vaadin 之书

中示例的简化

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

下面是我的代码。基于上面提到的 Vaadin 图表示例,我通过替换 Chart object with a simple Label 对象的使用来简化它。标签每秒更新一次,告诉您当前时间。

仅供示例使用——在real-world项目

中使用执行器

警告:我下面的示例是为简单起见而构建的,不打算作为生产代码 .休眠线程是一种管理计划的线程工作的粗糙而笨拙的方法。 Java 为此类工作提供了 Executor 便利。在一个 real-world 项目中,我将使用 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 来解决类似的关于 Push with Vaadin 的问题。

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

我的配置

我的代码在 NetBeans 8.0.2 中使用 Vaadin 7.3.7 和 Java 8 Update 25,在 Mac OS X 10.8 上使用 Tomcat 8.0.15。 5(山狮)。

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

如何使用这个例子

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

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

@Push注释

在中间的代码旁边,请注意我们如何将 @Push 注释添加到 MyUI class 定义中。

示例代码

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

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

原则上可以归结为以下几点:

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

    getUI().access(() -> layout.addComponent(new Label("Hello!")));
    
  3. 使用 Broadcaster pattern 向其他用户发布消息并订阅他们的消息。