CometD的消息推送

CometD 框架

CometD 框架是基於 HTTP 的事件驅動通訊解決方案。CometD 框架提供了一個 Java 服務器部件和一個 Java 客戶端部件,還有一個基於 jQuery 和 Dojo 的 JavaScript 客戶端庫。CometD 使用了一個叫 Bayeux 的標準化通訊協議,充許您針對於消息確認、流控制、同步、集羣等方面進行擴展。
CometD 的事件驅動方法很是適合事件驅動 Web 開發的新概念。正如傳統的桌面用戶界面那樣,全部的組件均經過總線進行通訊,以便發送通知和接收事件。所以全部的通訊都是異步的。
CometD 框架:javascript

  • 提供了一個稱爲 Oort 的集羣模塊,該模塊使您可以運行多個CometD Web 服務器,將它們看做是負載均衡器背後的集羣中的節點,從而擴展許多 HTTP 鏈接。
  • 支持安全策略,容許更具體地配置由誰經過哪條通道發送消息。- 更好地與 Spring 和 Google Guice(依賴注入框架)集成。

Bayeux 協議

它定義的消息經過命名通道進行路由而且可以進行交互傳 送:server -> client, client -> server 甚至 client -> client (固然仍是須要經過server中轉)。Bayeux 協議主要基於 HTTP 來傳輸低延遲的、異步的事件消息。採用Publish/Subscribe的模式,容許服務端異步push消息到客戶端。CommetD實現能夠基於流 (streaming) 和長輪詢 (long polling)。html

服務器和內部構件

CometD 與三個傳輸協議綁定在一塊兒:JSON、JSONP 和 WebSocket。他們都依賴於 Jetty Continuations 和 Jetty WebSocket API。在默認狀況下,能夠在 Jetty 六、Jetty 七、和 Jetty 8 中以及其餘全部支持 Servlet 3.0 Specification 的服務中使用 CometD。可使用與擴展相同的方式添加和開發傳輸協議。您應該可以編寫支持 Grizzly WebSocket API 和其餘 API 的傳輸協議,而後再在配置 CometD 服務器的步驟中添加這些協議。 Cometd是一個提供多種開發語言的Bayeux項目,由Dojo基金會提供支持。前端

Comet 的反向 Ajax

客戶端向服務端發送請求,當請求到達的時候服務端能夠當即將處理結果發送給客戶端,也能夠累計客戶端發送的請求再連續的發送給客戶端。
java

CometD 的構架視圖

Subscribe

訂閱是將訂閱某個Channel的客戶端所對應的ContinuationClient對象加入到對應的channel的subscribers列表中。訂閱成功後進行客戶端的長輪訓,服務端會將當前的請求封裝到一個Continuation中,並將Continuation對象設到ContinuationClient對象中,而後將ContinuationClient對象掛起。web

Publish

服務端接受到信息的時候,會找到訂閱的channel,而後進行數據的廣播。這個時候調用channel的push 方法,對每個訂閱當前channel客戶進行分發。將ContinuationClient中的Continuation喚醒resume。ajax

客戶端與服務端創建起鏈接
send信息到服務端的時候會帶上clientId,自己還帶上id且id是遞增

客戶端經過channel傳遞test1,服務端同時將信息返回

服務器中止,關閉服務的時候客戶端檢測信息
spring

前端畫面創建鏈接安全

(function($)
{
    var cometd = $.cometd;
    $(document).ready(function()
    {
    /**
         * Therefore the code that you put in the _connectionEstablished() function must be idempotent. In other words,
            make sure that if the _connectionEstablished() function is called more than one time,
            it will behave exactly as if it is called only once.
         * @returns
         */    
        function _connectionEstablished()
        {
            $('#body').append('<div>CometD Connection Established</div>');
        }

        function _connectionBroken()
        {
            $('#body').append('<div>CometD Connection Broken</div>');
        }

        function _connectionClosed()
        {
            $('#body').append('<div>CometD Connection Closed</div>');
        }

        // Function that manages the connection status with the Bayeux server
        var _connected = false;
        // 檢測會話鏈接是否創建
        function _metaConnect(message)
        {
            if (cometd.isDisconnected())
            {
                _connected = false;
                _connectionClosed();
                return;
            }

            var wasConnected = _connected;
            _connected = message.successful === true;
            if (!wasConnected && _connected)
            {
                _connectionEstablished();
            }
            else if (wasConnected && !_connected)
            {
                _connectionBroken();
            }
        }

        // Function invoked when first contacting the server and
        // when the server has lost the state of this client
        var loop=0;
        function _metaHandshake(handshake)
        {
            if (handshake.successful === true)
            {
                cometd.batch(function()
                {   //訂閱
                    cometd.subscribe('/hello', function(message)
                    {
                        $('#body').append('<div>Server Says: ' + message.data.greeting + '</div>');
                    });
                    // Publish on a service channel since the mge is for the server only
                    $("#btnTest").click(function(){
                         cometd.publish('/service/hello', { name: $("#txtValue").val()});
                    })
                });
            }
        }

        // Disconnect when the page unloads
        $(window).unload(function()
        {
            cometd.disconnect(true);
        });

        var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
        cometd.configure({
            url: cometURL,
            logLevel: 'debug',
        });
        //進行握手
        cometd.addListener('/meta/handshake', _metaHandshake);
        //創建鏈接
        cometd.addListener('/meta/connect', _metaConnect);       
        
        cometd.handshake();
    });
})(jQuery);

其它消息推送技術

  • ActiveMQ AJAX - publish and subscribe to JMS events directly from javascript in the browser. This is quite basic, with less bells and whistles than the other approaches, but because of it's simplicity, might be a good base to start with if you a) already use activemq, b) like not having too many layers of abstraction
  • Atmosphere - Event based framework, can auto detected the best communication mechanism based on which webserver and which broswer are currently in use. A pretty nice framework, which supports a full spread of browsers and web severs, even down to IE6. And there are examples of using Atmosphere with spring MVC and Spring Integration.
  • Cometd - An implementation of the Bayeux protocol (to auto-negotiate the best connection type) based on jetty/hightide. Jetty was the first java webserver to support continuations, now part of the latest Servlet spec. Cometd take Jetty and wraps it up with JS client libraries for autodetection of the best connection mechanism to the browser.
  • Vert.x - An event based server platform that you can build on top of. There has been some controversy around Vert.x recently when it's author left VMware, but VMware retained the project. It now looks like version 2 will be released from the Eclipse Foundation. Seems very promising, but quite low level. Not the kind of thing you just plug into an existing java web app.
  • HTML5 EventSource - Standards based way of sending events to the browser. No mechanism for sending events back to the server. It's interesting, but given you need to implment a fallback for IE6, IE7 and IE8, it might not be your best choice, for now.

文獻資料

cometd
wa-reverseajax
An Introduction To WebSockets
What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet
Servlet 3.0
push notification for java web app
cometd-java-examples服務器

相關文章
相關標籤/搜索