2009-03-06 15 views
6

Có cách nào để "đăng ký" từ GWT cho các đối tượng JSON phát trực tuyến và lắng nghe các sự kiện đến trên kết nối tiếp tục, mà không cố gắng tìm nạp chúng cùng một lúc không? Tôi tin rằng buzzword-du-jour cho công nghệ này là "Comet".GWT/Sao chổi: bất kỳ trải nghiệm nào?

Giả sử rằng tôi có dịch vụ HTTP mà mở giữ-sống kết nối và đưa đối tượng JSON với giá cổ phiếu đến đó trong thời gian thực:

{"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"}
...

Tôi cần nghe các sự kiện này và cập nhật các thành phần GWT (bảng, nhãn) trong thời gian thực. Có ý tưởng nào để làm nó không không?

Trả lời

6

Có một Comet Mô-đun GWT cho Streamhub:

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

StreamHub là một máy chủ Comet với một phiên bản cộng đồng miễn phí. Có một ví dụ về nó trong hành động here.

Bạn sẽ cần phải tải về máy chủ Streamhub Comet và tạo ra một SubscriptionListener mới, sử dụng ví dụ StockDemo như là một điểm khởi đầu, sau đó tạo ra một JsonPayload mới để truyền dữ liệu:

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

Tải JAR từ mã trang web google, thêm nó vào GWT dự án classpath của bạn và thêm bao gồm để mô-đun GWT của bạn:

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

Connect và đăng ký từ mã GWT của bạn:

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); 
... 

Sau đó xử lý các bản cập nhật như thế nào bạn thích trong người nghe cập nhật (cũng trong mã 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; 
      ... 
     } 
} 

Đừng quên bao gồm Streamhub-min.js trong các dự án GWT của bạn chính trang HTML.

+0

Xin chào. Có cách nào để vô hiệu hóa trình duyệt không làm biểu tượng 'tải' gây phiền nhiễu trên con trỏ tức là tải trình duyệt đó trong Chrome, hiển thị vòng tròn màu trắng gây phiền nhiễu. Như bạn có thể tưởng tượng, có một ứng dụng cần phải mở trong một thời gian dài và có biểu tượng tải lên liên tục được khá khó chịu! Cảm ơn. – Federer

1

Một số ý tưởng sơ bộ cho việc triển khai Comet cho GWT có thể được tìm thấy here... mặc dù tôi tự hỏi liệu có cái gì đó trưởng thành hơn không.

1

Ngoài ra, một số thông tin chi tiết về tích hợp GWT/Comet có sẵn there, sử dụng nhiều công nghệ cắt và chảy máu hơn: "Jetty Continuations". Đáng xem xét.

3

có thực sự là một thư viện cometd giống như cho gwt - http://code.google.com/p/gwteventservice/

Nhưng tôi đã không trực tiếp sử dụng nó, vì vậy không thể thực sự xác minh cho dù nó tốt hay không, nhưng doco có vẻ khá tốt. đáng thử.

Có một vài thứ khác tôi đã thấy, như thư viện gwt-rocket's cometd.

5

Tôi đã sử dụng kỹ thuật này trong một vài dự án, mặc dù nó không có vấn đề gì. Tôi nên lưu ý rằng tôi chỉ thực hiện điều này một cách cụ thể thông qua GWT-RPC, nhưng nguyên tắc là giống nhau đối với bất kỳ cơ chế nào bạn đang sử dụng để xử lý dữ liệu. Tùy thuộc vào chính xác những gì bạn đang làm, có thể không cần nhiều thứ phức tạp hơn.

Trước hết, ở phía khách hàng, tôi không tin rằng GWT có thể hỗ trợ đúng bất kỳ loại dữ liệu phát trực tuyến nào. Kết nối phải đóng trước khi máy khách thực sự có thể xử lý dữ liệu. Điều này có nghĩa là từ quan điểm máy chủ đẩy là khách hàng của bạn sẽ kết nối với máy chủ và chặn cho đến khi dữ liệu có sẵn tại thời điểm đó nó sẽ trở lại. Bất kỳ mã nào thực hiện trên kết nối đã hoàn thành sẽ ngay lập tức mở lại một kết nối mới với máy chủ để đợi thêm dữ liệu.

Từ phía máy chủ của mọi thứ, bạn chỉ cần thả vào chu kỳ chờ (gói đồng thời java đặc biệt thuận tiện cho việc này với các khối và thời gian chờ), cho đến khi có dữ liệu mới. Tại thời điểm đó, máy chủ có thể trả về gói dữ liệu xuống máy khách sẽ cập nhật cho phù hợp. Có một số cân nhắc tùy thuộc vào luồng dữ liệu của bạn như thế nào, nhưng sau đây là một vài suy nghĩ về:

  • Khách hàng có nhận được mọi cập nhật quan trọng không? Nếu vậy, sau đó máy chủ cần lưu trữ bất kỳ sự kiện tiềm năng nào giữa thời gian khách hàng nhận được một số dữ liệu và sau đó kết nối lại.
  • Có các bản cập nhật không? Nếu trường hợp này xảy ra, có thể sẽ khôn ngoan hơn khi đóng gói một số cập nhật và đẩy các khối vào một thời điểm vài giây thay vì yêu cầu khách hàng nhận được một bản cập nhật tại một thời điểm.
  • Máy chủ có thể sẽ cần một cách để phát hiện xem một khách hàng đã biến mất để tránh chồng chất lên một lượng lớn các gói được lưu trong bộ nhớ cache cho khách hàng đó hay không.

Tôi thấy có hai vấn đề với cách tiếp cận đẩy máy chủ. Với rất nhiều khách hàng, điều này có nghĩa là rất nhiều kết nối mở trên máy chủ web. Tùy thuộc vào máy chủ web được đề cập, điều này có thể có nghĩa là nhiều luồng được tạo và được mở. Thứ hai phải làm với giới hạn 2 yêu cầu cho mỗi tên miền của trình duyệt điển hình. Nếu bạn có thể phục vụ hình ảnh của bạn, css và nội dung tĩnh khác cho các tên miền cấp hai, vấn đề này có thể được giảm nhẹ.

+0

+1 Bài đăng tuyệt vời với một số thông tin chi tiết tuyệt vời. – Federer

+0

+1 Đây chính xác là cách tôi thực hiện. Các giải pháp cho vấn đề "rất nhiều chủ đề" được đánh vần là "yêu cầu treo" trong thông số Servlet 3.0. Jetty đã hỗ trợ sớm cho điều này trong 7.0. Tomcat gọi nó là thứ khác. –

0

Here bạn có thể tìm thấy mô tả (với một số mẫu nguồn) về cách thực hiện việc này cho Máy chủ ứng dụng WebSphere của IBM. Không nên quá khác biệt với Jetty hoặc bất kỳ máy chủ J2EE nào khác hỗ trợ Comet. Tóm lại, ý tưởng là: mã hóa đối tượng Java của bạn thành chuỗi JSON qua GWT RPC, sau đó sử dụng cometd gửi nó cho máy khách, nơi nó được nhận bởi Dojo, mã này sẽ kích hoạt mã JSNI của bạn, gọi các phương thức widget của bạn, nơi bạn deserialize đối tượng một lần nữa sử dụng GWT RPC. Thì đấy! :)

Trải nghiệm của tôi với thiết lập này là tích cực, không có vấn đề gì với nó ngoại trừ các câu hỏi bảo mật. Nó không thực sự rõ ràng làm thế nào để thực hiện bảo mật cho sao chổi trong trường hợp này ... Có vẻ Comet cập nhật servlet nên có các URL khác nhau và sau đó bảo mật J2EE có thể được áp dụng.

0

Dự án JBoss Errai có một xe buýt thông báo cung cấp tin nhắn hai chiều cung cấp một lựa chọn tốt cho cometd.

0

Chúng tôi đang sử dụng Bầu không khí Framewrok (http://async-io.org/) cho ServerPush/Comet trong ứng dụng GWT.

Về phía máy khách, Khung công tác có tích hợp GWT khá đơn giản. Ở phía máy chủ, nó sử dụng Servlet đơn giản.

Chúng tôi hiện đang sử dụng nó trong sản xuất với hơn 1000 người dùng đồng hành trong môi trường nhóm. Chúng tôi đã có một số vấn đề về cách mà phải được giải quyết bằng cách sửa đổi nguồn Atmosphere. Ngoài ra các tài liệu thực sự là mỏng.

Framework được sử dụng miễn phí.