Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Приложение dukeetf2

Пример приложения dukeetf2 , расположенного в каталоге tut-install/examples/websocket/dukeetf2/, демонстрирует, как использовать конечную точку веб-сокета для предоставления обновлённых данных веб-клиентам. Пример напоминает сервис, который предоставляет периодические обновления цены и объёма торгов биржевым инвестиционным фондом (ETF).

Здесь рассматриваются следующие темы:

Архитектура приложения dukeetf2

Приложение dukeetf2 состоит из конечной точки веб-сокета, Enterprise-бина и страницы HTML.

  • Конечная точка принимает подключения от клиентов и отправляет им обновления, когда становятся доступными новые данные о цене и объёме торгов.

  • Enterprise-бин обновляет информацию о цене и объёме каждую секунду.

  • HTML-страница использует код JavaScript для подключения к конечной точке веб-сокета, анализа входящих сообщений и обновления информации о цене и объёме без перезагрузки страницы.

Конечная точка

Конечная точка веб-сокета реализована в классе ETFEndpoint, который хранит все подключённые сессии в очереди и предоставляет метод, который вызывает Enterprise-бин, когда появляется новая информация, доступная для отправки:

@ServerEndpoint("/dukeetf")
public class ETFEndpoint {
   private static final Logger logger = Logger.getLogger("ETFEndpoint");
   /* Очередь для всех открытых сессий веб-сокета */
   static Queue<Session> queue = new ConcurrentLinkedQueue<>();

   /* PriceVolumeBean вызывает этот метод для отправки обновлений */
   public static void send(double price, int volume) {
      String msg = String.format("%.2f / %d", price, volume);
      try {
         /* Отправка обновления во все открытые сессии веб-сокета */
         for (Session session : queue) {
            session.getBasicRemote().sendText(msg);
            logger.log(Level.INFO, "Sent: {0}", msg);
         }
      } catch (IOException e) {
         logger.log(Level.INFO, e.toString());
      }
    }
    ...
}

Методы жизненного цикла конечной точки добавляют и удаляют сессии в очередь и из неё:

@ServerEndpoint("/dukeetf")
public class ETFEndpoint {
   ...
   @OnOpen
   public void openConnection(Session session) {
      /* Регистрация этого соединения в очереди */
      queue.add(session);
      logger.log(Level.INFO, "Connection opened.");
   }

   @OnClose
   public void closedConnection(Session session) {
      /* Удаление соединения из очереди */
      queue.remove(session);
      logger.log(Level.INFO, "Connection closed.");
   }

   @OnError
   public void error(Session session, Throwable t) {
      /* Удаление этого соединения из очереди */
      queue.remove(session);
      logger.log(Level.INFO, t.toString());
      logger.log(Level.INFO, "Connection error.");
   }
}

Enterprise-бин

Enterprise-бин использует сервис таймера для генерации новой информации о цене и объёме каждую секунду:

@Startup
@Singleton
public class PriceVolumeBean {
   /* Использование сервиса таймера контейнера */
   @Resource TimerService tservice;
   private Random random;
   private volatile double price = 100.0;
   private volatile int volume = 300000;
   private static final Logger logger = Logger.getLogger("PriceVolumeBean");

   @PostConstruct
   public void init() {
       /* Инициализация EJB и создание таймера */
       logger.log(Level.INFO, "Initializing EJB.");
       random = new Random();
       tservice.createIntervalTimer(1000, 1000, new TimerConfig());
   }

   @Timeout
   public void timeout() {
       /* Корректировка цены и объёма и отправка обновления */
       price += 1.0*(random.nextInt(100)-50)/100.0;
       volume += random.nextInt(5000) - 2500;
       ETFEndpoint.send(price, volume);
   }
}

Enterprise-бин вызывает метод send класса ETFEndpoint в методе timeout. Смотрите Использование сервиса таймера в главе 37 «Запуск примеров Enterprise-бина» для получения дополнительной информации о сервисе таймера.

HTML-страница

HTML-страница состоит из таблицы и кода JavaScript. Таблица содержит два поля, на которые ссылается код JavaScript:

<!DOCTYPE html>
<html>
<head>...</head>
<body>
  ...
  <table>
    ...
    <td id="price">--.--</td>
    ...
    <td id="volume">--</td>
    ...
  </table>
</body>
</html>

Код JavaScript использует API веб-сокетов для подключения к конечной точке сервера и определения Callback-метода для входящих сообщений. Callback-метод обновляет страницу новой информацией.

var wsocket;
function connect() {
   wsocket = new WebSocket("ws://localhost:8080/dukeetf2/dukeetf");
   wsocket.onmessage = onMessage;
}
function onMessage(evt) {
   var arraypv = evt.data.split("/");
   document.getElementById("price").innerHTML = arraypv[0];
   document.getElementById("volume").innerHTML = arraypv[1];
}
window.addEventListener("load", connect, false);

API веб-сокетов поддерживается большинством современных браузеров и широко используется при разработке веб-клиентов на HTML5.

Запуск приложения dukeetf2

В этом разделе описывается, как запустить пример dukeetf2 в IDE NetBeans и из командной строки.

Здесь рассматриваются следующие темы:

Запуск приложения dukeetf2 с IDE NetBeans

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В меню «Файл» выберите «Открыть проект».

  3. В диалоговом окне «Открыть проект» перейдите к:

    tut-install/examples/web/websocket
  4. Выберите каталог dukeetf2.

  5. Нажмите Открыть проект.

  6. На вкладке «Проекты» кликните правой кнопкой мыши проект dukeetf2 и выберите «Выполнить».

    Эта команда собирает и упаковывает приложение в WAR-файл (dukeetf2.war), расположенный в каталоге target/, развёртывает его на сервере и запускает окно веб-браузера со следующим URL:

    http://localhost:8080/dukeetf2/

    Откройте один и тот же URL на другой вкладке или в окне веб-браузера, чтобы увидеть, как обе страницы одновременно получают обновления цены и объёма.

Запуск приложения dukeetf2 с помощью Maven

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В окне терминала перейдите в:

    tut-install/examples/web/websocket/dukeetf2/
  3. Введите следующую команду для развёртывания приложения:

    mvn install
  4. Откройте окно веб-браузера и введите следующий URL:

    http://localhost:8080/dukeetf2/

    Откройте один и тот же URL на другой вкладке или в окне веб-браузера, чтобы увидеть, как обе страницы одновременно получают обновления цены и объёма.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)