Http被設計成了一個單向的通訊的協議,即客戶端發起一個request,而後服務器迴應一個response。這讓服務器很爲惱火:我特麼纔是老大,我竟然不能給小弟發消息。。。git
老大發火了,小弟們天然不能無動於衷,爲了能及時得到老大的消息,小弟們只好每隔一段時間跑去老大那裏問問,有沒有新的指示發出。這即是最先實現實時得到服務器數據的技術輪詢(Polling)。github
客戶端經過ajax不停去向服務器得到數據,檢查是否有新的數據更新。這種使用輪詢實現一種僞實時的狀態很容易,但效率偏低,通常而言,這種實時得到的數據,自己數據量不是很是大,而經過這種反覆地發起request的方式,每每形成的多是http的header信息比數據自己還多,並且大多數時候得到的數據都是重複無用的。(聽說最先還有經過不斷刷新客戶端頁面,來實現web實時通訊的狀況~ 我想應該木有哪一個客戶會受得了這種體驗。)web
「不值啊!咱哥幾個天天跑來跑去。拿到的都是一堆沒用的數據。」ajax
因而你們坐在一塊兒想,有什麼好辦法能不用總是跑腿又能夠得到新的信息及時行動呢?小的們靈機一動,下次咱們跑去老大那裏等着,等他老人家下了命令再回來。這就是基於 AJAX 的長輪詢(long-polling)方式實現的一種comet方式。由於ajax的調用是異步的,咱們能夠在頁面加載完畢以後,發起一個request請求,服務器端會阻塞request直到有數據傳遞或超時(timeout)才返回。客戶端處理完服務器返回的信息後,再次發出請求,從新創建鏈接。這樣周而復始。瀏覽器
基於 AJAX 的long-polling安全
另外還有一種comet模型,他的名字玄乎比長輪詢邪乎的多。。。叫The forever iframe technique。這名兒聽起來就高大上不少。其實就是在頁面中隱藏一個iframe標籤,而後將這個iframe的 SRC 屬性設爲對一個長鏈接的請求,服務器端就能源源不斷地往客戶端輸入數據。可是這種方法有一個很明顯的問題,各個瀏覽器會一直顯示頁面加載沒有完成,若是用戶是個強迫症,他必定會分分鐘關掉頁面的。TAT......服務器
forever iframe技術websocket
無論怎麼樣comet技術第一次實現了真正的實時通訊,並且能支持大量用戶,小的們今後老是能準確地得到老大的消息了。可是comet不會是一個沒有反作用的解決方案,因爲長期佔用鏈接,讓web喪失了無狀態高併發的特色,大量消耗了服務器帶寬和資源。網絡
「跑來跑去真是麻煩誒~http腫麼這麼麻煩呀。我們和老大之間整個新協議吧。」 併發
這個想法在小弟們中炸開了鍋!!! 在你們的千呼萬喚中,WebSocket協議登場了。哈哈哈哈哈~讓我來拯救各位吧~~~~
WebSocket協議是HTML5定義的一種新協議,它實現了瀏覽器與服務器全雙工通訊(full-duplex)。經過瀏覽器發出websocket連線請求,而後服務器發出迴應,創建一個聯繫的通道。小的們只用發個信息問老大:「首長好~」,老大回一個信兒:「同志們辛苦了!」這樣握手(handshaking)就完成了,websocket連線完成,經過websocket,咱們能夠完成真正的實時通訊了。
websocket容許經過JavaScript創建與遠程服務器的鏈接,從而實現客戶端與服務器間雙向的通訊。在websocket中有兩個方法:
1、send() 向遠程服務器發送數據
2、close() 關閉該websocket連接
websocket同時還定義了幾個監聽函數
一、onopen 當網絡鏈接創建時觸發該事件
二、onerror 當網絡發生錯誤時觸發該事件
三、onclose 當websocket被關閉時觸發該事件
四、onmessage 當websocket接收到服務器發來的消息的時觸發的事件,也是通訊中最重要的一個監聽事件。
websocket還定義了一個readyState屬性,這個屬性能夠返回websocket所處的狀態:
1、CONNECTING(0) websocket正嘗試與服務器創建鏈接
2、OPEN(1) websocket與服務器已經創建鏈接
3、CLOSING(2) websocket正在關閉與服務器的鏈接
4、CLOSED(3) websocket已經關閉了與服務器的鏈接
websocket的url開頭是ws,若是須要ssl加密可使用wss,當咱們調用websocket的構造方法構建一個websocket對象(new WebSocket(url))的以後,就能夠進行即時通訊了。
哈哈哈哈哈哈~老大經過websocket發話了:
晚上請吃飯!
小弟們趕忙行動起來~
相比comet技術,websocket不只節約了header的問題(websocket的head信息只有短短的2個字節)。更加劇要的是是通訊的穩定性,comet在遇到網絡問題以後,想要在不刷新頁面的狀況下恢復通訊,很是困難,而websocket中提供了onclose函數來處理斷開網絡後的狀況,這爲咱們與服務器的通訊提供了可靠的保障。在github上有一個js庫(https://github.com/joewalnes/reconnecting-websocket)就是經過這種方式來處理websocket斷網重連。
websocket看起來普遍實現只是時間問題了,固然這麼好用的websocket也不是沒有它的問題,websocket目前來看最大的問題是瀏覽器的支持(幸虧大部分的服務器軟件在比較新的版本中都已經支持了websocket),ie直到10纔開始支持這種協議,並且每一個瀏覽器最近在升級瀏覽器的時候,都會對websocket作出細微的調整。並且,想象你打開一個頁面,當這個頁面打開websocket鏈接而且執行一個內部IP地址的端口掃描,若是端口掃描發現了內部網絡上發現了一個開啓的80端口,一個隧道就可能經過你的瀏覽器創建。這樣作極可能最終繞過防火牆,而且容許訪問內部內容。因此安全問題,也是websocket如今面臨的一大隱患。