comet - gmail通知解除 - 信箱通知




Facebook,Gmail如何發送實時通知? (4)

更新

在我繼續接受upvotes這個,我認為這是合理的記住,這個答案是4歲。 網絡的發展速度非常快,所以請注意這個答案。

我最近有同樣的問題,並就這個問題進行了研究。

給出的解決方案稱為長輪詢,為了正確使用它,你必須確保你的AJAX請求有一個“大”超時並且在當前結束(超時,錯誤或成功)之後總是發出這個請求。

長輪詢 - 客戶端

在這裡,為了保持代碼簡潔,我將使用jQuery:

function pollTask() { 

    $.ajax({

        url: '/api/Polling',
        async: true,            // by default, it's async, but...
        dataType: 'json',       // or the dataType you are working with
        timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
        cache: false

    }).done(function (eventList) {  

       // Handle your data here
       var data;
       for (var eventName in eventList) {

            data = eventList[eventName];
            dispatcher.handle(eventName, data); // handle the `eventName` with `data`

       }

    }).always(pollTask);

}

記住(來自jQuery文檔 )非常重要:

在jQuery 1.4.x及以下版本中,如果請求超時,XMLHttpRequest對象將處於無效狀態; 訪問任何對象成員可能會拋出異常。 僅在Firefox 3.0+中,腳本和JSONP請求不能被超時取消; 腳本即使在超時時間後到達,也會運行。

長輪詢 - 服務器

它不是用任何特定的語言,但它會是這樣的:

function handleRequest () {  

     while (!anythingHappened() || hasTimedOut()) { sleep(2); }

     return events();

} 

在這裡, hasTimedOut將確保您的代碼不會永遠等待,並且發生的anythingHappened都會檢查是否有任何事件發生。 sleep是釋放你的線程來做其他事情,而沒有任何反應。 這些events將以JSON格式(或您喜歡的任何其他方式)返回events字典(或您可能更喜歡的任何其他數據結構)。

它肯定可以解決問題,但是,如果您擔心研究時的可擴展性和性能問題,那麼您可以考慮另一種解決方案。

使用套接字!

在客戶端,為了避免任何兼容性問題,請使用socket.io 。 它試圖直接使用套接字,並且在套接字不可用時具有回退到其他解決方案的功能。

在服務器端,使用NodeJS創建一個服務器( here示例)。 客戶端將訂閱由服務器創建的這個頻道(觀察者)。 每當必鬚髮送通知時,都會在此頻道中發布通知,並通知下標(客戶端)。

如果您不喜歡此解決方案,請嘗試APE( Ajax Push Engine )。

希望我幫助。

我已經閱讀了關於這個主題的一些帖子,答案是彗星,反向ajax,http流媒體,服務器推送等。

Gmail上的收到郵件通知如何工作?

GMail Chat如何在沒有客戶端交互的情況下發出AJAX請求?

我想知道是否有任何代碼引用可以用來編寫一個非常簡單的示例。 許多帖子或網站只是談論這項技術。 很難找到完整的示例代碼。 此外,似乎可以使用許多方法來實現彗星,例如隱藏IFrame,XMLHttpRequest。 在我看來,使用XMLHttpRequest是一個更好的選擇。 你如何看待不同方法的優缺點? Gmail使用哪一個?

我知道它需要在服務器端和客戶端進行。 有沒有PHP和Javascript示例代碼?



根據有關Facebook消息系統幻燈片 ,Facebook使用慧星技術向網絡瀏覽器“推送”消息。 Facebook的彗星服務器建立在開源的Erlang網絡服務器mochiweb上。

在下圖中,“通道簇”這個短語的意思是“彗星服務器”。

許多其他大型網站都建立了自己的慧星服務器,因為每家公司的需求都存在差異。 但是在開源慧星服務器上構建自己的慧星服務器是一種好方法。

你可以試試icomet ,一個用libevent構建的C1000K C ++慧星服務器。 icomet還提供了一個JavaScript庫,它很容易使用,操作簡單:

var comet = new iComet({
    sign_url: 'http://' + app_host + '/sign?obj=' + obj,
    sub_url: 'http://' + icomet_host + '/sub',
    callback: function(msg){
        // on server push
        alert(msg.content);
    }
});

icomet支持多種瀏覽器和操作系統,包括Safari(iOS,Mac),IE(Windows),Firefox,Chrome等。


長輪詢的一個重要問題是錯誤處理。 有兩種類型的錯誤:

  1. 在這種情況下,請求可能會超時,客戶端應立即重新建立連接。 在沒有消息到達的情況下,這是長輪詢中的正常事件。

  2. 網絡錯誤或執行錯誤。 這是客戶端應該優雅地接受並等待服務器重新聯機的實際錯誤。

主要問題是,如果您的錯誤處理程序立即為類型2錯誤重新建立連接,則客戶端將DOS服務器。

這兩個代碼示例的答案都沒有。

function longPoll() { 
        var shouldDelay = false;

        $.ajax({
            url: 'poll.php',
            async: true,            // by default, it's async, but...
            dataType: 'json',       // or the dataType you are working with
            timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
            cache: false

        }).done(function (data, textStatus, jqXHR) {
             // do something with data...

        }).fail(function (jqXHR, textStatus, errorThrown ) {
            shouldDelay = textStatus !== "timeout";

        }).always(function() {
            // in case of network error. throttle otherwise we DOS ourselves. If it was a timeout, its normal operation. go again.
            var delay = shouldDelay ? 10000: 0;
            window.setTimeout(longPoll, delay);
        });
}
longPoll(); //fire first handler