有没有办法从GWT"订阅"到JSON对象流并在keep-alive连接上监听传入事件,而不是试图一次性获取它们?我相信这项技术的流行语是"彗星".
假设我有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组件(表格,标签).有什么想法怎么做?
StreamHub有一个GWT Comet模块:
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,将其添加到您的GWT项目类路径并将包含添加到您的GWT模块:
从您的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.
我在几个项目中使用过这种技术,尽管它确实存在问题.我应该注意到我只是通过GWT-RPC专门完成了这个,但是无论你用什么机制来处理数据,原理都是一样的.根据您的具体操作,可能没有太多需要使事情复杂化.
首先,在客户端,我不相信GWT可以正确支持任何类型的流数据.在客户端实际处理数据之前必须关闭连接.从服务器推送的角度来看,这意味着您的客户端将连接到服务器并阻塞,直到数据可用,此时它将返回.无论在完成的连接上执行什么代码,都应立即重新打开与服务器的新连接以等待更多数据.
从服务器端开始,您只需进入一个等待周期(对于块和超时,java并发包特别方便),直到有新数据可用.在那个时间点,服务器可以将数据包返回到客户端,该客户端将相应地更新.根据您的数据流的不同,有很多注意事项,但这里有一些需要考虑的事项:
客户端每次更新都很重要吗?如果是这样,那么服务器需要在客户端获取某些数据然后重新连接之间缓存任何潜在事件.
是否会有更新的消息?如果是这种情况,可能更明智的是每隔几秒打包一次更新并按下块,而不是让客户端一次获得一次更新.
服务器可能需要一种方法来检测客户端是否已经离开以避免为该客户端堆积大量缓存包.
我发现服务器推送方法存在两个问题.对于大量客户端,这意味着Web服务器上有许多开放连接.根据所讨论的Web服务器,这可能意味着许多线程被创建并保持打开状态.第二个问题与典型浏览器每个域2个请求的限制有关.如果您能够为二级域提供图像,CSS和其他静态内容,则可以减轻此问题.