2014-11-25 158 views
9

我想在Angularjs中執行一個簡單的長輪詢請求 - 我發出GET請求,並掛起直到服務器響應。然後我再次發出請求並等待下一個響應 - 等等。Angularjs長輪詢

但是,由於某種原因,該代碼是相當不可靠的,錯過80%左右,從服務器發送的響應。

下面是我的代碼:

main.messages=[]; 
... 
main.poll=function(){ 
    $http.get('http://localhost:8080/message') 
    .success(function(data){ 
    console.log(data); 
    main.messages.push(data); 
    main.poll(); 
    }) 
    .error(...) 
}; 

有沒有,我很想念這裏的東西明顯?

服務器可以檢測到瀏覽器被連接,並且服務器不發送響應而上面的代碼沒有得到響應(無控制檯輸出和無差錯)。我試着用郵差(擴展名爲chrome)提出這個請求,並且長時間輪詢在那裏完美工作,所以我認爲問題出現在這裏。

更新:該問題僅在谷歌瀏覽器中出現,並且只有當多個選項卡同時執行長輪詢時纔會發生。在創建和關閉新的選項卡時,有一些看似隨機的行爲。

+0

這只是故事的一半,因爲您沒有包含超時代碼或服務器端代碼,因此很難可靠地進行診斷。 – 2014-11-25 10:16:19

+0

超時碼? – jitin 2014-11-25 10:19:41

回答

6

我發現是什麼導致了這一點。 Chrome瀏覽器只會一次性拋出給定網址一個標籤。如果用戶有多個選項卡打開請求相同的longpoll,Chrome會在第一個選項卡中等待第二個選項卡中的輪詢開始之前完成第一個選項卡中的longpoll。

我認爲瀏覽器的外觀,在長查詢請求爲「未響應的服務器。」當您嘗試在新選項卡中發出相同的請求時,瀏覽器實際上不會再次發出相同的請求以節省資源。如果您查看網絡選項卡,它將顯示待處理的請求。但這是'謊言',瀏覽器實際上是在等待服務器響應第一個標籤的請求。一旦它從服務器獲得第一個選項卡請求的響應,纔會向服務器查詢第二個選項卡的請求。

換句話說,瀏覽器(Chrome和Opera)通常不會做兩個長查詢請求,同時在相同的終點 - 即使這些請求是由兩種不同的標籤來。

然而,在一定的時間量後,有時它決定釋放用於所述第二標籤請求也是如此。但我無法爲此找出任何規則。如果您使用相同的請求打開3個選項卡,關閉第一個會導致來自其餘兩個選項卡的兩個同時請求。但是如果你有6個選項卡打開,關閉第一個會導致只有3個併發請求,而不是5.我相信會有一些規則來管理這種行爲,但我想我們必須編寫代碼,假設請求可能會或可能不會發生同時瀏覽器可能會等待一個請求完成,然後才能開始第二個。

Safari不具備此行爲 - 它會同時通過多個選項卡發出多個請求。但是Chrome和Opera確實顯示了這種行爲。

因此,而不是同時向所有連接的客戶端「廣播」的數據,我現在改變我的代碼以使用時間戳來計算出有多少數據在客戶端的需求,然後發送數據。

+0

Chrome/Opera的任何已知解決方法? – 2015-01-06 15:37:44

+7

一種方法是:爲每個網址添加一個臨時隨機後綴,並在服務器上忽略它。像這樣:'localhost:8080/longpoll?rand = 12345',並且在解析服務器中的url時忽略rand部分。這樣,從瀏覽器的角度來看,每個標籤都試圖長時間輪詢一個不同的URL(即使其數量不同),即使它從服務器的角度來看也是一樣的。因此,即使有多個選項卡,您也可以同時獲得長時間投擲。這是處理它的一種方法。 – jitin 2015-01-08 03:39:32

+2

@rbaghbanli是的,對於那個可以使用當前時間戳的臨時部分,每次都會是唯一的:) – 2015-04-27 10:43:51