WebSocket
WebSocket
是一種支持雙向通訊
網(wǎng)絡(luò)通信協(xié)議。- 意思就是服務(wù)器可以
主動(dòng)向客戶端推送信息
,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息
- 屬于服務(wù)器推送技術(shù)的一種.
特點(diǎn):
(1)建立在 TCP 協(xié)議
之上,服務(wù)器端的實(shí)現(xiàn)比較容易。
(2)與 HTTP 協(xié)議
有著良好的兼容性。默認(rèn)端口也是80和443,并且握手階段
采用 HTTP 協(xié)議,因此握手時(shí)不容易屏蔽,能通過各種 HTTP 代理服務(wù)器
。
(3)數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
(4)可以發(fā)送文本
,也可以發(fā)送二進(jìn)制數(shù)據(jù)
(blob
對(duì)象或Arraybuffer
對(duì)象)
(5)收到的數(shù)據(jù)類型 可以使用binaryType 指定, 顯式指定收到的二進(jìn)制數(shù)據(jù)類型
(6)沒有同源限制
,客戶端可以與任意服務(wù)器通信。
(7)協(xié)議標(biāo)識(shí)符是ws(握手http)
(如果加密,則為wss(tcp +TLS)
),服務(wù)器網(wǎng)址就是 URL。
WebSocket對(duì)象
WebSocket對(duì)象
提供了用于創(chuàng)建和管理WebSocket 連接
,以及可以通過該連接發(fā)送和接收數(shù)據(jù)的 API
。
使用 WebSocket()
構(gòu)造函數(shù)來構(gòu)造一個(gè) WebSocket
。
為什么需要websocket
Hypertext Transfer Protocol (HTTP) 協(xié)議
一種無(wú)狀態(tài)的、應(yīng)用層的、以請(qǐng)求/應(yīng)答方式運(yùn)行的協(xié)議,它使用可擴(kuò)展的語(yǔ)義和自描述消息格式,與基于網(wǎng)絡(luò)的超文本信息系統(tǒng)靈活的互動(dòng).
- 因?yàn)閔ttp 通信只能由客戶端發(fā)起,服務(wù)器返回查詢結(jié)果,HTTP 協(xié)議做不到服務(wù)器主動(dòng)向客戶端推送信息, 服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知就非常麻煩。
- 我們只能使用輪詢:每隔一段時(shí)候,就發(fā)出一個(gè)詢問,了解服務(wù)器有沒有新的信息。最典型的場(chǎng)景就是聊天室。
- 輪詢的效率低,非常浪費(fèi)資源(因?yàn)楸仨毑煌_B接,或者 HTTP 連接始終打開);
Chrome 請(qǐng)求列表:分析 WebSocket
過濾器(過濾資源xhr js ws css ws等):
- 按照類型: ws
- 屬性過濾: is:running
表格列 Frames
Data: 消息負(fù)載。 如果消息為純文本,直接顯示。 二進(jìn)制操作嗎顯示操作碼名稱和代碼(Continuation Frame、 Binanry Frame、 Connection Close Frame、 Ping Frame或者Pong Frame)
Length: 消息負(fù)載的長(zhǎng)度 以字節(jié)為單位
Time: 收到或者發(fā)送的時(shí)間。
消息顏色
- 發(fā)送到服務(wù)器的文本消息為淺綠色
- 接收到的文本消息為白色
- WebSocket 操作碼 為淺黃色
- 錯(cuò)誤為淺紅色
WbeSocket 的成本 對(duì)比http
1、實(shí)時(shí)性與可伸縮性。
犧牲了簡(jiǎn)單性。
2、網(wǎng)絡(luò)效率與無(wú)狀態(tài): 請(qǐng)求1基于請(qǐng)求2
犧牲了簡(jiǎn)單性與可見性
websocket 的心跳保持 對(duì)比http
- (http 長(zhǎng)連接只能基于簡(jiǎn)單的超時(shí)(常見為65s))
- websocket 鏈接基于
ping/pong 心跳機(jī)制維持
設(shè)計(jì)哲學(xué): 在web約束下暴露tcp 給上層
元數(shù)據(jù)
- http 協(xié)議頭部會(huì)存放元數(shù)據(jù).
- websocket 上傳輸?shù)膽?yīng)用層存放元數(shù)據(jù)
基于幀: 不是基于字節(jié)流(http, tcp)
- 每一幀要么存放
字符數(shù)據(jù)
,要么承載二進(jìn)制
數(shù)據(jù)
基于瀏覽器的同源策略模型個(gè)(非瀏覽器無(wú)效)
可以使用Access-Control-Allow-Origin 等頭部
基于URI
、子協(xié)議
支持同主機(jī)``同端口
上的多個(gè)服務(wù)
幀格式示意圖
ABNF 描述的幀格式
ws-frame = frame-fin ; 1 bit in length
frame-rsv1 ; 1 bit in length
frame-rsv2 ; 1 bit in length
frame-rsv3 ; 1 bit in length
frame-opcode ; 4 bits in length
frame-masked ; 1 bit in length
frame-payload-length ; 3 種長(zhǎng)度
[ frame-masking-key ] ; 32 bits in length
frame-payload-data ; n*8 bits in ; length, where ; n >= 0
復(fù)制代碼
紅色: 2 字節(jié)必然存在的幀首部
數(shù)據(jù)幀格式: Rsv 保留值
RSV1/RSV2/RSV3:默認(rèn)為 0,僅當(dāng)使用 extension 擴(kuò)展時(shí),由擴(kuò)展決定其值
數(shù)據(jù)幀格式:幀類型
- 持續(xù)幀
0: 繼續(xù)前一幀 - 非控制幀
1: 文本幀(utf-8)
2:二進(jìn)制幀
3-7: 為非控制幀保留 - 控制幀
8: 關(guān)閉幀
9: 心跳幀ping
A: 心跳幀pong
B-F:控制幀保留
URI 格式
1、ws-uri: ws://[host][:port][path][?query]
端口port默認(rèn) 80
2、wss-uri: wss://[host][:port][path][?query]
端口port 默認(rèn)443
客戶端提供信息
host、port 主機(jī)端口
schema: 是否基于SSL
訪問的資源:uri
握手隨機(jī)數(shù):Sec-WebSocket-Key
選擇的子協(xié)議:Sec-WebSocket-Protocol
擴(kuò)展協(xié)議:Sec-WebSocket-Extensions
CORS:Origin
如何證明握手被服務(wù)器接受?預(yù)防意外
請(qǐng)求中的 Sec-WebSocket-Key 隨機(jī)數(shù)
Sec-WebSocket-Key: A1EEou7Nnq6+BBZoAZqWlg==
響應(yīng)中的 Sec-WebSocket-Accept 證明值
GUID(RFC4122):258EAFA5-E914-47DA-95CA-C5AB0DC85B11
? 值構(gòu)造規(guī)則:BASE64(SHA1(Sec-WebSocket-KeyGUID))
? 拼接值:A1EEou7Nnq6+BBZoAZqWlg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
? SHA1 值:713f15ece2218612fcadb1598281a35380d1790f
? BASE 64 值:cT8V7OIhhhL8rbFZgoGjU4DReQ8=
? 最終頭部:Sec-WebSocket-Accept: cT8V7OIhhhL8rbFZgoGjU4DReQ8=