Вопрос

Есть ли способ «подписаться» на поток объектов GWT на JSON и прослушивать входящие события при постоянном соединении, не пытаясь получить их все одновременно?Я считаю, что модным словечком для этой технологии является «Комета».

Предположим, что у меня есть HTTP-сервис, который открывает поддерживающее соединение и помещает туда JSON-объекты с входящими котировками акций в режиме реального времени:

{"symbol": "AAPL", "bid": "88.84", "ask":"88.86"}
{"symbol": "AAPL", "bid": "88.85", "ask":"88.87"}
{"symbol": "IBM", "bid": "87.48", "ask":"87.49"}
{"symbol": "GOOG", "bid": "305.64", "ask":"305.67"}
...

Мне нужно прослушивать эти события и обновлять компоненты GWT (таблицы, метки) в реальном времени.Есть идеи, как это сделать?

Это было полезно?

Решение

Существует модуль кометы GWT для StreamHub:

http://code.google.com/p/gwt-comet-streamhub /

StreamHub - это сервер Comet с бесплатной версией для сообщества. Вот пример этого в действии здесь .

Вам потребуется загрузить сервер StreamHub Comet и создать новый SubscriptionListener, использовать пример StockDemo в качестве отправной точки, а затем создать новый JsonPayload для потоковой передачи данных:

Payload payload = new JsonPayload("AAPL");
payload.addField("bid", "88.84");
payload.addField("ask", "88.86");
server.publish("AAPL", payload);
...

Загрузите JAR с сайта кода Google, добавьте его в путь к классам проектов GWT и добавьте включение в свой модуль GWT:

<inherits name="com.google.gwt.json.JSON" />
<inherits name="com.streamhub.StreamHubGWTAdapter" />

Подключитесь и подпишитесь на ваш код GWT:

StreamHubGWTAdapter streamhub = new StreamHubGWTAdapter();
streamhub.connect("http://localhost:7979/");
StreamHubGWTUpdateListener listener = new StockListener();
streamhub.subscribe("AAPL", listener);
streamhub.subscribe("IBM", listener);
streamhub.subscribe("GOOG", listener);
...

Затем обработайте обновления так, как вам нравится, в прослушивателе обновлений (также в коде GWT):

public class StockListener implements StreamHubGWTUpdateListener {
      public void onUpdate(String topic, JSONObject update) {
          String bid = ((JSONString)update.get("bid")).stringValue();
          String ask = ((JSONString)update.get("ask")).stringValue();
          String symbol = topic;
          ...
      }
}

Не забудьте включить streamhub-min.js в главную HTML-страницу ваших проектов GWT.

Другие советы

Я использовал эту технику в нескольких проектах, хотя у нее есть свои проблемы.Должен отметить, что я сделал это только через GWT-RPC, но принцип один и тот же для любого механизма, который вы используете для обработки данных.В зависимости от того, что именно вы делаете, возможно, нет необходимости слишком усложнять ситуацию.

Во-первых, что касается клиента, я не верю, что GWT может должным образом поддерживать какие-либо потоковые данные.Соединение должно закрыться, прежде чем клиент сможет фактически обработать данные.С точки зрения отправки на сервер это означает, что ваш клиент будет подключаться к серверу и блокироваться до тех пор, пока данные не станут доступны, после чего он вернется.Какой бы код ни выполнялся при завершенном соединении, он должен немедленно повторно открыть новое соединение с сервером, чтобы дождаться дополнительных данных.

Со стороны сервера вы просто переходите в цикл ожидания (для этого особенно удобен пакет Java concurrent с блоками и таймаутами), пока не станут доступны новые данные.В этот момент сервер может вернуть пакет данных клиенту, который обновит его соответствующим образом.Существует множество соображений в зависимости от того, как выглядит ваш поток данных, но вот некоторые из них, о которых стоит подумать:

  • Важно ли для клиента получать каждое обновление?Если да, то серверу необходимо кэшировать любые потенциальные события между моментом получения клиентом некоторых данных и повторным подключением.
  • Будет ли много обновлений?В этом случае, возможно, было бы разумнее упаковать несколько обновлений и отправлять их порциями каждые несколько секунд, а не заставлять клиента получать одно обновление за раз.
  • Серверу, вероятно, понадобится способ определить, ушел ли клиент, чтобы избежать накопления огромного количества кэшированных пакетов для этого клиента.

Я обнаружил две проблемы с подходом принудительной отправки с сервера.При большом количестве клиентов это означает множество открытых соединений на веб-сервере.В зависимости от рассматриваемого веб-сервера это может означать, что создается и остается открытым множество потоков.Второе связано с типичным ограничением браузера в 2 запроса на домен.Если вы можете обслуживать свои изображения, CSS и другой статический контент из доменов второго уровня, эту проблему можно решить.

действительно есть библиотека типа комет для gwt - http://code.google.com / р / gwteventservice /

Но я не использовал его лично, так что я не могу поручиться за то, хорош он или нет, но документ выглядит неплохо. Стоит попробовать.

Есть несколько других, которые я видел, например, комета gwt-rocket библиотека.

Некоторые предварительные идеи для реализации Comet для GWT можно найти здесь ... хотя мне интересно, есть ли что-то более зрелое.

Кроме того, некоторые сведения об интеграции GWT / Comet доступны там , используя даже более передовые технологии: «Jetty Continuations». Стоит взглянуть.

Здесь вы можете найти описание (с некоторыми примеры исходного кода) того, как это сделать для IBM WebSphere Application Server. Не должно сильно отличаться от Jetty или любого другого J2EE-сервера с поддержкой Comet. Вкратце, идея такова: закодируйте ваш Java-объект в строку JSON через GWT RPC, затем с помощью cometd отправьте его клиенту, где он получен Dojo, который запускает ваш код JSNI, который вызывает методы вашего виджета, где вы десериализуете объект снова используя GWT RPC. Вуаля! :)

Мой опыт работы с этой настройкой положительный, с ней не было никаких проблем, кроме вопросов безопасности. Не совсем понятно, как реализовать защиту для кометы в этом случае ... Похоже, что сервлеты обновления Comet должны иметь разные URL, и тогда может быть применена безопасность J2EE.

В проекте JBoss Errai есть шина сообщений, которая обеспечивает двунаправленный обмен сообщениями, что является хорошей альтернативой cometd.

Мы используем Atmosphere Framewrok ( http://async-io.org/ ) для ServerPush / Comet в приложении GWT.

На стороне клиента интегрированная среда GWT довольно проста. На стороне сервера он использует простой сервлет.

В настоящее время мы используем его в работе с более чем 1000 одновременно работающих пользователей в кластерной среде. У нас были некоторые проблемы на пути, которые должны были быть решены путем модификации источника атмосферы. Также документация действительно тонкая.

Framework можно использовать бесплатно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top