基于HTTP的長連接配接,是一種通過長輪詢方式實作"伺服器推"的技術,它彌補了HTTP簡單的請求應答模式的不足,極大地增強了程式的實時性和互動性。
一、什麼是長連接配接、長輪詢?
用通俗易懂的話來說,就是用戶端不停的向伺服器發送請求以擷取最新的資料資訊。這裡的“不停”其實是有停止的,隻是我們人眼無法分辨是否停止,它隻是一種快速的停下然後又立即開始連接配接而已。
二、長連接配接、長輪詢的應用場景
長連接配接、長輪詢一般應用與WebIM、ChatRoom和一些需要及時互動的網站應用中。其真實案例有:WebQQ、Hi網頁版、Facebook IM等。
歡迎大家繼續支援和關注我的部落格: <a target="_blank" href="http://hoojo.cnblogs.com/">http://hoojo.cnblogs.com</a> <a target="_blank" href="http://blog.csdn.net/IBM_hoojo">http://blog.csdn.net/IBM_hoojo</a> 也歡迎大家和我交流、探讨IT方面的知識。
三、優缺點
輪詢:用戶端定時向伺服器發送Ajax請求,伺服器接到請求後馬上傳回響應資訊并關閉連接配接。 優點:後端程式編寫比較容易。 缺點:請求中有大半是無用,浪費帶寬和伺服器資源。 執行個體:适于小型應用。 長輪詢:用戶端向伺服器發送Ajax請求,伺服器接到請求後hold住連接配接,直到有新消息才傳回響應資訊并關閉連接配接,用戶端處理完響應資訊後再向伺服器發送新的請求。 優點:在無消息的情況下不會頻繁的請求,耗費資源小。 缺點:伺服器hold連接配接會消耗資源,傳回資料順序無保證,難于管理維護。 執行個體:WebQQ、Hi網頁版、Facebook IM。 長連接配接:在頁面裡嵌入一個隐蔵iframe,将這個隐蔵iframe的src屬性設為對一個長連接配接的請求或是采用xhr請求,伺服器端就能源源不斷地往用戶端輸入資料。 優點:消息即時到達,不發無用請求;管理起來也相對友善。 缺點:伺服器維護一個長連接配接會增加開銷。 執行個體:Gmail聊天 Flash Socket:在頁面中内嵌入一個使用了Socket類的 Flash 程式JavaScript通過調用此Flash程式提供的Socket接口與伺服器端的Socket接口進行通信,JavaScript在收到伺服器端傳送的資訊後控制頁面的顯示。 優點:實作真正的即時通信,而不是僞即時。 缺點:用戶端必須安裝Flash插件;非HTTP協定,無法自動穿越防火牆。 執行個體:網絡互動遊戲。
四、實作原理
所謂長連接配接,就是要在用戶端與伺服器之間建立和保持穩定可靠的連接配接。其實它是一種很早就存在的技術,但是由于浏覽器技術的發展比較緩慢,沒有為這種機制的實作提供很好的支援。是以要達到這種效果,需要用戶端和伺服器的程式共同配合來完成。通常的做法是,在伺服器的程式中加入一個死循環,在循環中監測資料的變動。當發現新資料時,立即将其輸出給浏覽器并斷開連接配接,浏覽器在收到資料後,再次發起請求以進入下一個周期,這就是常說的長輪詢(long-polling)方式。如下圖所示,它通常包含以下幾個關鍵過程:1. 輪詢的建立 建立輪詢的過程很簡單,浏覽器發起請求後進入循環等待狀态,此時由于伺服器還未做出應答,是以HTTP也一直處于連接配接狀态中。 2. 資料的推送 在循環過程中,伺服器程式對資料變動進行監控,如發現更新,将該資訊輸出給浏覽器,随即斷開連接配接,完成應答過程,實作“伺服器推”。 3. 輪詢的終止 輪詢可能在以下3種情況時終止: 3.1. 有新資料推送 當循環過程中伺服器向浏覽器推送資訊後,應該主動結束程式運作進而讓連接配接斷開,這樣浏覽器才能及時收到資料。 3.2. 沒有新資料推送 循環不能一直持續下去,應該設定一個最長時限,避免WEB伺服器逾時(Timeout),若一直沒有新資訊,伺服器應主動向浏覽器發送本次輪詢無新資訊的正常響應,并斷開連接配接,這也被稱為“心跳”資訊。 3.3. 網絡故障或異常 由于網絡故障等因素造成的請求逾時或出錯也可能導緻輪詢的意外中斷,此時浏覽器将收到錯誤資訊。 4. 輪詢的重建 浏覽器收到回複并進行相應處理後,應馬上重新發起請求,開始一個新的輪詢周期。![]()
Web 通信 之 長連接配接、長輪詢(long polling)
五、程式設計
1、普通輪詢 Ajax方式
用戶端代碼片段
用戶端實作的就是用一種普通輪詢的結果,比較簡單。利用setInterval不間斷的重新整理來擷取伺服器的資源,這種方式的優點就是簡單、及時。缺點是連結多數是無效重複的;響應的結果沒有順序(因為是異步請求,當發送的請求沒有傳回結果的時候,後面的請求又被發送。而此時如果後面的請求比前面的請求要先傳回結果,那麼目前面的請求傳回結果資料時已經是過時無效的資料了);請求多,難于維護、浪費伺服器和網絡資源。 伺服器端代碼
2、普通輪詢 iframe方式
這裡的用戶端程式是利用隐藏的iframe向伺服器端不停的拉取資料,将iframe擷取後的資料填充到頁面中即可。同ajax實作的基本原理一樣,唯一不同的是當一個請求沒有響應傳回資料的情況下,下一個請求也将開始,這時候前面的請求将被停止。如果要使程式和上面的ajax請求一樣也可以辦到,那就是給每個請求配置設定一個獨立的iframe即可。下面是傳回的結果:其中紅色是沒有成功傳回請求就被停止(後面請求開始)掉的請求,黑色是成功傳回資料的請求。![]()
Web 通信 之 長連接配接、長輪詢(long polling)
3、長連接配接iframe方式
這種方式雖然保證了請求的順序,但是它不會處理請求延時的錯誤或是說很長時間沒有傳回結果的請求,它會一直等到傳回請求後才能建立下一個iframe請求,總會和伺服器保持一個連接配接。和以上輪詢比較,缺點就是消息不及時,但保證了請求的順序。
4、ajax實作長連接配接
上面這段代碼就是才有Ajax的方式完成長連接配接,主要優點就是和伺服器始終保持一個連接配接。如果目前連接配接請求成功後,将更新資料并且繼續建立一個新的連接配接和伺服器保持聯系。如果連接配接逾時或發生異常,這個時候程式也會建立一個新連接配接繼續請求。這樣就大大節省了伺服器和網絡資源,提高了程式的性能,進而也保證了程式的順序。![]()
Web 通信 之 長連接配接、長輪詢(long polling)
六、總結
現代的浏覽器都支援跨域資源共享(Cross-Origin Resource Share,CORS)規範,該規範允許XHR執行跨域請求,是以基于腳本的和基于iframe的技術已成為了一種過時的需要。 把Comet做為反向Ajax的實作和使用的最好方式是通過XMLHttpRequest對象,該做法提供了一個真正的連接配接句柄和錯誤處理。當然你選擇經由HTTP長輪詢使用XMLHttpRequest對象(在伺服器端挂起的一個簡單的Ajax請求)的Comet模式,所有支援Ajax的浏覽器也都支援該種做法。 基于HTTP的長連接配接技術,是目前在純浏覽器環境下進行即時互動類應用開發的理想選擇,随着浏覽器的快速發展,html5将為其提供更好的支援和更廣泛的應用。在html5中有一個websocket 可以很友好的完成長連接配接這一技術,網上也有相關方面的資料,這裡也就不再做過多介紹。