websocket是什么?
答: 它是一種網絡通信協議,是 HTML5
開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。
為什么需要websocket? 疑問? 我們已經有了 HTTP 協議,為什么還需要另一個協議?它能帶來什么好處?
答:是因為 HTTP 協議有一個缺陷,通信只能由客戶端發起,然后服務器再做出響應,服務器不能主動向客戶端推送消息。這種單向請求的特點,注定了如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。我們只能使用"輪詢":每隔一段時候,就發出一個詢問,了解服務器有沒有新的信息。最典型的場景就是聊天室。輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。WebSocket協議的最大特點是服務器可以主動向客戶端推送消息,客戶端也可以主動向服務器發送消息,是真正的雙向平等對話,屬於服務器推送技術的一種。
其他特點包括:
(1)建立在 TCP 協議之上,服務器端的實現比較容易。
(2)與 HTTP 協議有着良好的兼容性。默認端口也是80和443,並且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器。
(3)數據格式比較輕量,性能開銷小,通信高效。
(4)可以發送文本,也可以發送二進制數據。
(5)沒有同源限制,客戶端可以與任意服務器通信。
(6)協議標識符是ws
(如果加密,則為wss
),服務器網址就是 URL。 ws://example.com:80/some/path
WebSocket目前支持兩種統一資源標志符ws
和wss
,類似於HTTP和HTTPS。
實現原理
瀏覽器發出webSocket的連線請求,服務器發出響應,這個過程稱為握手
,握手的過程只需要一次,就可以實現持久連接。
握手與連接
瀏覽器發出連線請求,此時的request如下:
通過get
可以表明此次連接的建立是以HTTP協議為基礎的,返回101狀態碼。
如果不是101狀態碼,表示握手升級的過程失敗了
101是Switching Protocols,表示服務器已經理解了客戶端的請求,並將通過Upgrade 消息頭通知客戶端采用不同的協議來完成這個請求。在發送這個響應后的空檔,將http升級到webSocket。
WebSocket 的握手是一個標准的 HTTP GET 請求,但要帶上兩個協議升級的專用頭字段:
“Connection: Upgrade”,表示要求協議“升級”;
“Upgrade: websocket”,表示要“升級”成 WebSocket 協議。
另外,為了防止普通的 HTTP 消息被“意外”識別成 WebSocket,握手消息還增加了兩個額外的認證用頭字段(所謂的“挑戰”,Challenge):
Sec-WebSocket-Key:一個 Base64 編碼的 16 字節隨機數,作為簡單的認證密鑰;
Sec-WebSocket-Version:協議的版本號,當前必須是 13。
服務器接到瀏覽器的連線請求返回結果如下:
Upgrade和Connection來告訴瀏覽器,服務已經是基於webSocket協議的了,讓瀏覽器也遵循這個協議
Sec-WebSocket-Accept是服務端確認后並加密后的Sec-WebSocket-Accept
至此,webSocket連接成功,接下來就是webSocket的協議了。