GWT / Comet: есть опыт? - PullRequest
6 голосов
/ 06 марта 2009

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

Предположим, у меня есть HTTP-сервис, который открывает keep-alive соединение и помещает туда объекты 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 (таблицы, метки) в режиме реального времени. Есть идеи как это сделать?

Ответы [ 8 ]

6 голосов
/ 23 июля 2009

Существует модуль кометы 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.

5 голосов
/ 08 марта 2009

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

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

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

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

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

3 голосов
/ 08 марта 2009

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

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

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

1 голос
/ 06 марта 2009

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

1 голос
/ 06 марта 2009

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

0 голосов
/ 26 февраля 2014

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

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

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

Framework бесплатна для использования.

0 голосов
/ 03 декабря 2011

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

0 голосов
/ 29 января 2010

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

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

...