WebSocket是什麼
Wiki上是這樣介紹的:WebSocket是一種在單個TCP連接上進行全雙工通訊的協議。
這裏做個補充:是HTML5開始提供的一種瀏覽器與服務器進行全雙工通訊的網絡技術,屬於應用層協議。它基於TCP傳輸協議,並複用HTTP的握手通道。WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向數據傳輸。
WebSocket產生的背景
說到WebSocket產生的背景,就必須得先了解HTTP的通信機制。
HTTP的生命週期通過Request來界定,也就是一個Request 一個Response,那麼在HTTP1.0中,這次HTTP請求就結束了。在HTTP1.1中進行了改進,使得有一個keep-alive,也就是說,在一個HTTP連接中,可以發送多個Request,接收多個Response。但是請記住 Request = Response , 在HTTP中永遠是這樣,也就是說一個request只能有一個response。而且這個response也是被動的,不能主動發起。
所以,爲了創建一個具有雙向通信機制的web應用時(如web IM),就只能利用http輪詢的方式,分爲短輪詢和長輪詢,具體可以學習ajax和comet技術。
輪詢這種方式,有很多缺點,比如每次請求,都有很多重複的信息(較長的HTTP頭),浪費很多資源和帶寬,此外,這種方式會有一定的時延,對於需要即時通訊的應用是難以被接受的。
於是,就有了WebSocket協議。
WebSocket建立連接
WebSocket只需要一次握手,並且爲了兼容現有的HTTP的服務端組件,在HTTP請求上做了升級完成握手。具體指的是,客戶端通過HTTP請求與WebSocket服務端協商升級協議。協議升級完成後,後續的數據交換則遵照WebSocket的協議。
握手過程如下:
1. 客戶端瀏覽器發起協議升級請求
GET ws://127.0.0.1:8080/websocketTest/user000 HTTP/1.1
Host: 127.0.0.1:8080
Connection: Upgrade
Upgrade: websocket
Origin: http://localhost:8080
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Sec-WebSocket-Key: 5J5p7v3DZ8Tosy2W0g9UYQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Connection:Upgrade:表示要升級協議
Upgrade:websocket:表示要升級到websocket協議。
Sec-WebSocket-Version:13:表示websocket的版本。如果服務端不支持該版本,需要返回一個Sec-WebSocket-Versionheader,裏面包含服務端支持的版本號。
Sec-WebSocket-Key:與後面服務端響應首部的Sec-WebSocket-Accept是配套的,提供基本的防護,比如惡意的連接,或者無意的連接。
Sec-WebSocket-Extension:客戶端通過包含一個|Sec-WebSocket-Extensions|頭字段請求擴展
2. 服務端響應協議升級
HTTP/1.1 101
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: py9zdlc/o6/uW2v87YlCOCY6PKo=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Date: Sat, 12 May 2018 02:50:16 GMT
Sec-WebSocket-Accept根據客戶端請求首部的Sec-WebSocket-Key計算出來。
計算公式爲:
將Sec-WebSocket-Key跟258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接。
通過SHA1計算出摘要,並轉成base64字符串。
WebSocket優點
1. 服務器與客戶端之間交換的標頭信息很小,大概只有2字節
2. 客戶端與服務器都可以主動傳送數據給對方,真正的全雙工
3. 不用頻繁創建TCP請求及銷燬請求,減少網絡帶寬資源的佔用,同時也節省服務器資源
4. 支持擴展。ws協議定義了擴展,用戶可以擴展協議,或者實現自定義的子協議。(比如支持自定義壓縮算法等)