【问题标题】:GWT / Comet: any experience?GWT/彗星:有什么经验吗?
【发布时间】:2009-03-06 12:18:30
【问题描述】:

有没有办法从 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 组件(表格、标签)。有什么想法吗?

【问题讨论】:

    标签: json gwt comet


    【解决方案1】:

    StreamHub 有一个 GWT Comet 模块:

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

    StreamHub 是带有免费社区版的 Comet 服务器。有一个实际的例子here

    您需要下载 StreamHub Comet 服务器并创建一个新的 SubscriptionListener,使用 StockDemo 示例作为起点,然后创建一个新的 JsonPayload 来流式传输数据:

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

    从 google 代码站点下载 JAR,将其添加到您的 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;
              ...
          }
    }
    

    不要忘记在您的 GWT 项目主 HTML 页面中包含 streamhub-min.js。

    【讨论】:

    • 嘿。有没有办法禁止浏览器在光标上执行烦人的“加载”符号,即在 Chrome 中加载它,会出现一个烦人的白色圆圈。正如您可以想象的那样,拥有一个需要长时间打开的应用程序并且不断加载该加载符号会变得相当烦人!谢谢。
    【解决方案2】:

    我在几个项目中使用了这种技术,尽管它确实存在问题。我应该注意,我只是专门通过 GWT-RPC 完成了这项工作,但无论您使用何种机制来处理数据,原理都是相同的。取决于您具体在做什么,可能没有太多需要过度复杂化的事情。

    首先,在客户端,我认为 GWT 不能正确支持任何类型的流数据。在客户端可以实际处理数据之前,连接必须关闭。从服务器推送的角度来看,这意味着您的客户端将连接到服务器并阻塞,直到数据可用,此时它将返回。在完成的连接上执行的任何代码都应立即重新打开与服务器的新连接以等待更多数据。

    从服务器端,您只需进入一个等待周期(java 并发包特别方便地处理阻塞和超时),直到有新数据可用。在那个时间点,服务器可以将数据包返回给客户端,客户端将相应地更新。根据您的数据流情况,有很多考虑因素,但这里有一些需要考虑:

    • 客户端获取每一个更新重要吗?如果是这样,那么服务器需要缓存客户端获取一些数据然后重新连接之间的任何潜在事件。
    • 会有大量更新吗?如果是这种情况,最好每隔几秒打包多个更新并一次下推数据块,而不是让客户端一次获得一个更新。
    • 服务器可能需要一种方法来检测客户端是否已离开,以避免为该客户端堆积大量缓存包。

    我发现服务器推送方法存在两个问题。对于大量客户端,这意味着 Web 服务器上有大量打开的连接。根据所讨论的 Web 服务器,这可能意味着要创建和保持打开大量线程。第二个与典型浏览器对每个域 2 个请求的限制有关。如果您能够为二级域提供图像、css 和其他静态内容,则可以缓解此问题。

    【讨论】:

    • +1 这正是我的做法。 “大量线程”问题的解决方案在 Servlet 3.0 规范中被拼写为“可挂起的请求”。 Jetty 在 7.0 中对此进行了早期支持。 Tomcat 叫它别的名字。
    【解决方案3】:

    确实有一个类似彗星的 gwt 库 - http://code.google.com/p/gwteventservice/

    但是我没有亲自使用过,所以不能真正保证它的好坏,但是doco看起来还不错。值得一试。

    还有一些我见过的,比如gwt-rocket's cometd library。

    【讨论】:

      【解决方案4】:

      可以在here... 找到一些关于为 GWT 实现 Comet 的初步想法,但我想知道是否有更成熟的东西。

      【讨论】:

        【解决方案5】:

        此外,there 还提供了有关 GWT/Comet 集成的一些见解,它使用了更尖端的技术:“Jetty Continuations”。值得一看。

        【讨论】:

          【解决方案6】:

          Here 您可以找到有关如何为 IBM WebSphere Application Server 执行此操作的描述(带有一些源示例)。与 Jetty 或任何其他支持 Comet 的 J2EE 服务器应该不会有太大的不同。简而言之,这个想法是:通过 GWT RPC 将您的 Java 对象编码为 JSON 字符串,然后使用 Cometd 将其发送到客户端,Dojo 接收它,触发您的 JSNI 代码,调用您的小部件方法,在其中反序列化对象再次使用 GWT RPC。瞧! :)

          我对这种设置的体验是积极的,除了安全问题之外没有任何问题。在这种情况下如何实现彗星的安全性并不清楚......似乎彗星更新servlet应该有不同的URL,然后可以应用J2EE安全性。

          【讨论】:

            【解决方案7】:

            JBoss Errai 项目有一个消息总线,它提供双向消息传递,是 Cometd 的一个很好的替代方案。

            【讨论】:

              【解决方案8】:

              我们在 GWT 应用程序中将 Atmosphere Framewrok(http://async-io.org/) 用于 ServerPush/Comet。

              在客户端框架具有非常简单的 GWT 集成。在服务器端,它使用普通的 Servlet。

              我们目前正在生产环境中使用它,集群环境中有 1000 多个并发用户。我们在途中遇到了一些问题,必须通过修改 Atmosphere 源来解决。文档也很薄。

              框架可以免费使用。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-14
                • 1970-01-01
                • 2011-08-13
                • 2011-07-19
                • 2011-08-12
                相关资源
                最近更新 更多