關於對WebSocket的一些介紹
什麼是WebSocket
WebSocket protocol 是HTML5 一種新的協議。
它是實現了瀏覽器與伺服器全雙工通訊。
HTML5定義了WebSocket 協議,能更好的節省伺服器資源和頻寬並達到實時通訊。
問什麼會使用WebSocket
HTML頁面在剛剛開始出現的時候是靜態的,不能夠進行互動。
直到後來有了JavaScript ,在一定程度上解決了這個問題,但是JavaScript 剛出現的時候並不能和伺服器進行互動。
直到Ajax 的出現,Ajax 有效的解決了頁面和伺服器段進行互動的問題。不過Ajax 有一個問題,就是所有的請求都必須由客戶端發起,服務端進行響應,如果伺服器端有最新的訊息,難以即時的傳送到客戶端上去。
在WebSocket 技術出現之前,為了讓客戶端能夠即時的活服務端的資料,採用瞭如下三種方案。
輪詢
這是最簡單的一種解決方案,也就是客戶端在固定的時間間隔下(一般是1秒)不停的向伺服器端傳送請求,檢視伺服器端是否有最新的資料,伺服器端如果有最新的資料,則返回給客戶端。如果服務端沒有,則返回一個空的json 或者xml 文件。
這種實現方式看起來很簡單,但是弊端也很明顯,就是會有大量的無效請求,服務端的資源被大大的浪費了。
長連線
長連線和輪詢有些許類似,不同的是服務端不是每次都會響應客戶端的請求,只有在伺服器有最新資料的時候才會響應客戶端的請求。
這種方式很明顯會節省網路的資源和伺服器資源,但是也會存在一些問題:
- 如果瀏覽器在伺服器響應之前有新資料要傳送就只能建立一個新的併發請求,或者先嚐試斷掉當前請求然後再建立新的請求。
- TCP 和HTTP 規範中都有可能出現連線超時的情況,所以所謂的長連線並不能一直持續,服務端和客戶端的連線需要定期的連線和關閉再連線。
Applet和Flash
這兩個技術除了可以讓我們的HTML 頁面更加絢麗之外,還可以解決訊息推送的問題。開發者可以用一個畫素嗲大小的普通透明的Apple 或者Flash ,然後將之內嵌在頁面中,然後這個Applet 或者Flash 中的程式碼建立出一個Socket 連線,這種連線方式消除了HTTP協議中的各種限制。
當伺服器有訊息傳送到客戶端的時候,開發者可以在Applet 或者Flash中呼叫JavaScript 函式,然後更新頁面。
當瀏覽器有資料要傳送給伺服器的時候也一樣,通過Applet 或者Flash 來傳遞。
這種方式真正的實現了全雙工通訊,但是也存在問題:
- 瀏覽器必須能夠執行Java 或者Flash
- 無論是Applet 還是Flash 都存在安全問題
- 隨著HTML5 標準在瀏覽器中廣泛支援,Flash下架已經被提上日程
WebSocket
引入
通過在客戶端在請求頭HTTPConnection : Upgrade 來希望升級協議。
通過Upgrade 頭中指定一個或者多個協議的列表(這些協議必須相容HTTP/1.1)。
在伺服器收到請求之後,如果接受升級請求,將會返回一個101的狀態碼,表示轉換請求協議同時相應Upgrade頭中時通 ‘單個值’,這個單個值就是請求協議列表中伺服器支援的第一個協議。
通過各種各樣的協議從而建立不同的TCP通訊。瀏覽器並不會讓開發者隨意去這麼做,而是要制定某些協議,就這樣webSocket應運而生!
使用HTTP/1.1升級的WebSocket
一個WebSocket請求首先使用正常的HTTP請求以特定的模式訪問一個URL,這個URL 有兩種模式,分別是ws 和 wss 對應HTTP協議中的http 和https 。
請求頭中除了Connection : Upgrade 之外還有一個 Upgrade : websocket,它們兩個將共同告訴伺服器將連線升級為WebScket 這樣的全雙工協議。
如此,在握手完成之後,文字訊息或者其他二進位制訊息就可以同時在兩個方向上進行傳送,而不需要關閉和重建連線,此時的客戶端和服務端關係其實是對等的,它們都可以相互想對方主動發訊息。
這裡需要注意:
ws 和wss 模式並不能算作HTTP協議的一部分,因為HTTP請求和請求頭並不包含URL模式,HTTP請求只能在請求的第一行中包含相對與伺服器的URL,在Host頭中包含域名,而WebSocket中特有的ws 和wss 模式主要用於通知瀏覽器和API 是希望使用SSL/TSL(wss) ,還是希望使用不加密的方法(ws)進行連線。
WebSocket協議的優勢
- 由於WebSocket連線在埠80(ws) 或者443(wss) 上建立,與HTTP使用的埠相同,這樣,基本上所有的防火牆都不會阻塞WebSocket 連線。
- WebSocket使用HTTP 協議進行握手,因此它可以自然而然的整合到網路瀏覽器和HTTP 伺服器中。
- 心跳檢測(ping、pong)將會反覆的傳送,進而保持WebSoket連線幾乎一直出於活躍狀態。
一般來說是這樣,一個節點週期性的傳送一個小資料包到另一個節點(ping),而另一個節點則使用了包含了相同資料的資料包作為響應(pong),這樣兩個節點都處於連線狀態。- 使用該協議,當訊息啟動或者到達的時候,伺服器和客戶端都可以知道。
- WebSocket連線關閉時將傳送一個特殊的關閉訊息。
- WebSocket支援跨域,可以避免Ajax的限制。
- HTTP規範要求瀏覽器將併發連線數限制為每個主機名兩個連線,但是當我們使用了WebSocket的時候,當握手完成之後該限制就不存在了,因為此時的連線已經不再是HTTP。
WebSocket協議的用途
- 網頁上的線上聊天
- 多人線上遊戲
- 線上股票網站
- 線上即時新聞網站
- 高清視訊流
- 應用叢集之間的通訊
- 遠端系統/軟體的狀態和效能的實時監控
本文參考資料 : 《JaveEE程式設計》