2011-12-12 38 views
3

我正在研究一個實現長時間拋出的應用程序,因爲我希望用戶在到達時立即收到通知。我有這部分工作,但我也需要擴展這與一個JavaScript函數,每20秒發送一個'心跳'到服務器。Javascript:每個客戶端有兩個連接?

我的問題:如何在不完全中斷代碼20秒的情況下執行此操作(以便在計數時其他javascript仍在執行中),並且是否有某種方法可以爲此使用第二個連接?因爲我不希望當心跳被髮送給用戶時,我的長時間中斷被打斷。

任何想法?

+0

如果一個定時器的超時時間爲20000毫秒,並且在它完成服務器異步請求後又睡了20000毫秒? – ComputerSaysNo

+0

如果客戶端中斷了http連接,那麼服務器肯定會註冊該連接。你應該能夠抓住這個事件。 – bennedich

+0

@bennedich:不要以爲連接關閉時會產生一個事件,我不知道服務器如何知道它。 – networkprofile

回答

2

你並不需要維護多個連接你想要什麼實現。 Javascript的異步特性允許連接在處理其他事情時保持活動狀態。您可能認爲JavaScript的XHR被阻塞,因爲它是單線程的。

由於事件循環模型,javascript中的XHR是非阻塞的 - JavaScript引擎一直處於循環狀態,檢查註冊的調用是否已完成以及是否應該處理其回調。這允許其操作是非阻塞的,從而允許單個JavaScript應用程序處理多個XHR長輪詢請求。

如果您能夠使用jQuery作爲請求,它會很好地包裝XHR:http://api.jquery.com/jQuery.ajax/。有了這個,你可以定義超時20秒並立即處理它(重新啓動與服務器的連接)。

另外 - 你可能希望考慮你的服務器堆棧來優化長輪詢。確保您的Web服務器不會爲每個請求產生一個線程(如Apache 2.2) - 否則您將很快用完系統資源!如果您可以使用node.js(這對處理多個同時發生的請求很有用),請查看socket.io庫作爲服務器端和客戶端解決方案(http://socket.io/#home)。

5

使用setInterval(yourHearbeatFunction, 20000),它不鎖定Javascript執行線程。所以,longpolled請求將盡快處理。

+0

問題是,如果一個心跳超過20秒完成,您將開始堆疊打開的請求,這會減慢瀏覽器速度。這很可能不是問題,因爲超時時間爲20秒,但如果時間較短,則可能是問題。 – Ariel

7

雖然下面的線程很舊,但它表明瀏覽器在任何時候都允許通過XMLHttpRequest進行多個連接。

How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

如果你有一個長輪詢會話或者使用一個XMLHttpRequest或實現彗星的任何其他方式,你仍然可以創建另一個請求到同一臺服務器作爲一個的setInterval或setTimeout函數的一部分,直到你到達通過瀏覽器,所有你需要確保實行有限的限制是,用戶在使用XHR建設的同步標誌:

var heartbeatXhr = new XMLHttpRequest(); 
heartbeatXhr.open('GET', '/polling-url', true); // true for asynchronous