標籤:style http color java 使用 os io 資料
Http被設計成了一個單向的通訊的協議,即用戶端發起一個request,然後伺服器回應一個response。這讓伺服器很為惱火:我特麼才是老大,我居然不能給小弟發訊息。。。
輪詢
老大發火了,小弟們自然不能無動於衷,為了能及時獲得老大的訊息,小弟們只好每隔一段時間跑去老大那裡問問,有沒有新的指示發出。這便是最早實現即時獲得伺服器資料的技術輪詢(Polling)。
用戶端通過ajax不停去向伺服器獲得資料,檢查是否有新的資料更新。這種使用輪詢實現一種偽即時的狀態很容易,但效率偏低,一般而言,這種即時獲得的資料,本身資料量不是非常大,而通過這種反覆地發起request的方式,往往造成的可能是http的header資訊比資料本身還多,而且大多數時候獲得的資料都是重複無用的。(據說最早還有通過不斷重新整理用戶端頁面,來實現web即時通訊的情況~ 我想應該木有哪個客戶會受得了這種體驗。)
Comet
“不值啊!咱哥幾個每天跑來跑去。拿到的都是一堆沒用的資料。”
於是大家坐在一起想,有什麼好辦法能不用老是跑腿又可以獲得新的資訊及時行動呢?小的們靈機一動,下次我們跑去老大那裡等著,等他老人家下了命令再回來。這就是基於 AJAX 的長輪詢(long-polling)方式實現的一種comet方式。因為ajax的調用是非同步,我們可以在頁面載入完畢之後,發起一個request請求,伺服器端會阻塞request直到有資料傳遞或逾時(timeout)才返回。用戶端處理完伺服器返回的資訊後,再次發出請求,重建立立串連。這樣周而復始。
基於 AJAX 的long-polling
另外還有一種comet模型,他的名字玄乎比長輪詢邪乎的多。。。叫The forever iframe technique。這名兒聽起來就高大上很多。其實就是在頁面中隱藏一個iframe標籤,然後將這個iframe的 SRC 屬性設為對一個長串連的請求,伺服器端就能源源不斷地往用戶端輸入資料。但是這種方法有一個很明顯的問題,各個瀏覽器會一直顯示頁面載入沒有完成,如果使用者是個強迫症,他一定會分分鐘關掉頁面的。TAT......
forever iframe技術
不管怎麼樣comet技術第一次實現了真正的即時通訊,而且能支援大量使用者,小的們從此總是能準確地獲得老大的訊息了。但是comet不會是一個沒有副作用的解決方案,由於長期佔用串連,讓web喪失了無狀態高並發的特點,大量消耗了伺服器頻寬和資源。
WebSocket登場
“跑來跑去真是麻煩誒~http腫麼這麼麻煩呀。咱們和老大之間整個新協議吧。”
這個想法在小弟們中炸開了鍋!!! 在大家的千呼萬喚中,WebSocket協議登場了。哈哈哈哈哈~讓我來拯救各位吧~~~~
WebSocket協議是HTML5定義的一種新協議,它實現了瀏覽器與伺服器全雙工系統通訊(full-duplex)。通過瀏覽器發出websocket連線請求,然後伺服器發出回應,建立一個聯絡的通道。小的們只用發個資訊問老大:“首長好~”,老大回一個信兒:“同志們辛苦了!”這樣握手(handshaking)就完成了,websocket連線完成,通過websocket,我們可以完成真正的即時通訊了。
websocket允許通過JavaScript建立與遠程伺服器的串連,從而實現用戶端與伺服器間雙向的通訊。在websocket中有兩個方法:
1、send() 向遠程伺服器發送資料
2、close() 關閉該websocket連結
websocket同時還定義了幾個監聽函數
1、onopen 當網路連接建立時觸發該事件
2、onerror 當網路發生錯誤時觸發該事件
3、onclose 當websocket被關閉時觸發該事件
4、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現在面臨的一大隱患。