面試官:說說對WebSocket的理解?應(yīng)用場景?
本文轉(zhuǎn)載自微信公眾號「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請聯(lián)系JS每日一題公眾號。
一、是什么
WebSocket,是一種網(wǎng)絡(luò)傳輸協(xié)議,位于OSI模型的應(yīng)用層??稍趩蝹€(gè)TCP連接上進(jìn)行全雙工通信,能更好的節(jié)省服務(wù)器資源和帶寬并達(dá)到實(shí)時(shí)通迅
客戶端和服務(wù)器只需要完成一次握手,兩者之間就可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸
圖片
從上圖可見,websocket服務(wù)器與客戶端通過握手連接,連接成功后,兩者都能主動(dòng)的向?qū)Ψ桨l(fā)送或接受數(shù)據(jù)
而在websocket出現(xiàn)之前,開發(fā)實(shí)時(shí)web應(yīng)用的方式為輪詢
不停地向服務(wù)器發(fā)送 HTTP 請求,問有沒有數(shù)據(jù),有數(shù)據(jù)的話服務(wù)器就用響應(yīng)報(bào)文回應(yīng)。如果輪詢的頻率比較高,那么就可以近似地實(shí)現(xiàn)“實(shí)時(shí)通信”的效果
輪詢的缺點(diǎn)也很明顯,反復(fù)發(fā)送無效查詢請求耗費(fèi)了大量的帶寬和 CPU資源
二、特點(diǎn)
全雙工
通信允許數(shù)據(jù)在兩個(gè)方向上同時(shí)傳輸,它在能力上相當(dāng)于兩個(gè)單工通信方式的結(jié)合
例如指 A→B 的同時(shí) B→A ,是瞬時(shí)同步的
二進(jìn)制幀
采用了二進(jìn)制幀結(jié)構(gòu),語法、語義與 HTTP 完全不兼容,相比http/2,WebSocket更側(cè)重于“實(shí)時(shí)通信”,而HTTP/2 更側(cè)重于提高傳輸效率,所以兩者的幀結(jié)構(gòu)也有很大的區(qū)別
不像 HTTP/2 那樣定義流,也就不存在多路復(fù)用、優(yōu)先級等特性
自身就是全雙工,也不需要服務(wù)器推送
協(xié)議名
引入ws和wss分別代表明文和密文的websocket協(xié)議,且默認(rèn)端口使用80或443,幾乎與http一致
ws://www.chrono.com
ws://www.chrono.com:8080/srv
wss://www.chrono.com:445/im?user_id=xxx
握手
WebSocket也要有一個(gè)握手過程,然后才能正式收發(fā)數(shù)據(jù)
客戶端發(fā)送數(shù)據(jù)格式如下:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Connection:必須設(shè)置Upgrade,表示客戶端希望連接升級
Upgrade:必須設(shè)置Websocket,表示希望升級到Websocket協(xié)議
Sec-WebSocket-Key:客戶端發(fā)送的一個(gè) base64 編碼的密文,用于簡單的認(rèn)證秘鑰。要求服務(wù)端必須返回一個(gè)對應(yīng)加密的“Sec-WebSocket-Accept應(yīng)答,否則客戶端會(huì)拋出錯(cuò)誤,并關(guān)閉連接
Sec-WebSocket-Version :表示支持的Websocket版本
服務(wù)端返回的數(shù)據(jù)格式:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat
HTTP/1.1 101 Switching Protocols:表示服務(wù)端接受 WebSocket 協(xié)議的客戶端連接
Sec-WebSocket-Accep:驗(yàn)證客戶端請求報(bào)文,同樣也是為了防止誤連接。具體做法是把請求頭里“Sec-WebSocket-Key”的值,加上一個(gè)專用的 UUID,再計(jì)算摘要
優(yōu)點(diǎn)
較少的控制開銷:數(shù)據(jù)包頭部協(xié)議較小,不同于http每次請求需要攜帶完整的頭部
更強(qiáng)的實(shí)時(shí)性:相對于HTTP請求需要等待客戶端發(fā)起請求服務(wù)端才能響應(yīng),延遲明顯更少
保持創(chuàng)連接狀態(tài):創(chuàng)建通信后,可省略狀態(tài)信息,不同于HTTP每次請求需要攜帶身份驗(yàn)證
更好的二進(jìn)制支持:定義了二進(jìn)制幀,更好處理二進(jìn)制內(nèi)容
支持?jǐn)U展:用戶可以擴(kuò)展websocket協(xié)議、實(shí)現(xiàn)部分自定義的子協(xié)議
更好的壓縮效果:Websocket在適當(dāng)?shù)臄U(kuò)展支持下,可以沿用之前內(nèi)容的上下文,在傳遞類似的數(shù)據(jù)時(shí),可以顯著地提高壓縮率
二、應(yīng)用場景
基于websocket的事實(shí)通信的特點(diǎn),其存在的應(yīng)用場景大概有:
彈幕
媒體聊天
協(xié)同編輯
基于位置的應(yīng)用
體育實(shí)況更新
股票基金報(bào)價(jià)實(shí)時(shí)更新
參考文獻(xiàn)
https://zh.wikipedia.org/wiki/WebSocket
https://www.oschina.net/translate/9-killer-uses-for-websockets
https://vue3js.cn/interview