Минимальный пример приложения Push in Vaadin 7 ( "@Push" )

Я хочу увидеть самый минимальный пример использования новой технологии Push в Vaadin 7, такой как новая аннотация @Push.

У меня возникают проблемы с получением server-push для работы в моем приложении. Я хотел бы попробовать простое примерное приложение, прежде чем пытаться исправить свое приложение.

Ответ 1

Упрощение примера в книге Ваадина

Book Of Vaadin включает в себя главу о Push, включая пример с использованием Vaadin Charts.

Ниже мой код. В то время как на основе этого примера Vaadin Charts, упомянутого выше, я упростил его, заменив использование Chart с помощью простого Label. Метка обновляется каждую секунду или около того, чтобы сообщить вам текущее время.

screen shot of example Vaadin app telling current time in UTC as text

Только для примера - использование Исполнителя в реальном проекте

Предостережение. Мой пример ниже построен для простоты, не предназначен как производственный код. Спящий поток - грубый и неловкий способ управлять запланированной работой с резьбой. Java предоставляет средство Executor для такого рода работ. В реальном проекте я бы использовал ScheduledExecutorService, а не один спальный Thread, чтобы запланировать нашу задачу (говорящего времени). Совет: Никогда не используйте Timer в среде Servlet. Для более полного и более реального примера см. мой ответ к аналогичному Вопросу о Push с Ваадином.

В этом примере я использовал другие ярлыки, такие как: я размещаю виджет 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).

Технология Push относительно новая, особенно WebSocket. Обязательно используйте последние версии вашего веб-сервера, например последние обновления для Tomcat 7 или 8.

Как использовать этот пример

Этот код представляет собой один файл, файл MyUI.java. Чтобы использовать этот код:

  • Создайте новое приложение Vaadin по умолчанию в своей IDE по выбору.
  • Получить этот пример успешно, прежде чем изменять.
  • Замените содержимое класса 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();
            }
        }
    }
}

Ответ 2

Здесь - простой, но полный пример Vaadin 8, демонстрирующий, как использовать API-интерфейсы push и Java EE для отправки сообщений между различными пользовательскими интерфейсами используя шаблон Broadcaster, описанный в Vaadin docs. Если вы не заинтересованы в обмене сообщениями или вещании другим пользователям, просмотрите ReceiveMessageUI.

В принципе все сводится к следующему:

  • Аннотировать пользовательский интерфейс Vaadin с помощью @Push, чтобы включить push сервера (по умолчанию через соединение WebSocket)
  • Обменивайте обновления пользовательского интерфейса с помощью access() при обращении к нему из других потоков, по умолчанию происходит автоматическая отправка обновлений:

    getUI().access(() -> layout.addComponent(new Label("Hello!")));
    
  • Используйте шаблон Broadcaster для публикации сообщений другим пользователям и подписки на их сообщения.