WebSocket 协议简介
為什么需要WebSocket 協(xié)議?
眾所周知,HTTP 協(xié)議是一個遵循請求-響應(yīng)模式的協(xié)議。這種模式有兩個特點:1. 由客戶端先發(fā)起請求,然后等待服務(wù)器的響應(yīng)。2. 服務(wù)器不能在沒有接收到客戶端請求時,就發(fā)送數(shù)據(jù)。也就是說,客戶端和服務(wù)器之間的通信是單向的。
在某些應(yīng)用中,通常有服務(wù)器向客戶端推送數(shù)據(jù)的需求,也就是需要客戶端和服務(wù)器之間能夠雙向通信。而使用現(xiàn)有的HTTP協(xié)議不能很好地實現(xiàn)這個需求,于是 HTTP 協(xié)議的升級版——WebSocket 協(xié)議被發(fā)明出來。
協(xié)議概述
WebSocket 協(xié)議包括兩部分:握手和數(shù)據(jù)傳輸。握手時會使用 HTTP 協(xié)議,所以說它是 HTTP 協(xié)議的升級版。
握手
客戶端發(fā)起握手時,會發(fā)送如下格式的 HTTP GET 請求:
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
Host 頭部就不用說了。
Upgrade 和 Connection 頭部表明要求服務(wù)器升級到 WebSocket 協(xié)議。
Sec-WebSocket-Key 頭部是一串 Base64 編碼的隨機(jī)字符串,用于握手驗證。
Sec-WebSocket-Version 頭部指明協(xié)議版本。
Origin 和 Sec-WebSocket-Protocol 頭部是可選的,后者表示客戶端支持的子協(xié)議。通常這兩個頭部都可以忽略。
服務(wù)器在收到握手請求時,回復(fù)如下的 HTTP 101 響應(yīng)完成握手(協(xié)議升級):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Upgrade 和 Connection 頭部表明服務(wù)器已經(jīng)升級到 WebSocket 協(xié)議。
Sec-WebSocket-Accept 頭部是為了給客戶端做驗證,它是的值是根據(jù)客戶端 Sec-WebSocket-Key 頭部的值使用某種算法計算出來的。
數(shù)據(jù)傳輸
握手成功后的數(shù)據(jù)傳輸過程就與 HTTP 協(xié)議沒有任何關(guān)系了。傳輸過程中,任意一方都可以自由地發(fā)送數(shù)據(jù)。協(xié)議中的數(shù)據(jù)傳輸單元稱作消息,一個消息包含一個或多個數(shù)據(jù)幀,每個數(shù)據(jù)幀都是消息的一個分片。WebSocket 數(shù)據(jù)幀的格式如下:
FIN,標(biāo)志位。值為1時表示是一個消息的最后一個分片。
Opcode,4位。表示數(shù)據(jù)幀的類型,有如下值:
0x0。是一個連續(xù)的幀,即它的類型與上一個幀的類型相同。
0x1。是一個文本幀。
0x2。是一個二進(jìn)制幀。
0x8。是一個關(guān)閉幀。
0x9。是一個 ping 幀。
0xa。是一個 pong 幀。
關(guān)閉幀、ping 幀和pong 幀都是控制幀,ping 幀和pong 幀可用來做心跳。
Mask,標(biāo)志位。值為1時表示數(shù)據(jù)已經(jīng)做了掩碼操作。
Payload length,數(shù)據(jù)長度。它的值為0-125時,就表示數(shù)據(jù)長度。它的值為126時,接下來的16位(Extended payload length 字段)表示數(shù)據(jù)長度。它的值為127時,表示接下來的64位(16位的 Extended payload length 字段和48位的 Extended payload length continued 字段)表示數(shù)據(jù)長度。
Masking-key,Mask標(biāo)志為1時,表示一個32位的數(shù)據(jù)掩碼。Mask標(biāo)志為0時,該字段不存在。
Payload Data,數(shù)據(jù)。
結(jié)束傳輸
當(dāng)雙方不需要再傳輸數(shù)據(jù)時,一端發(fā)送關(guān)閉幀(不能分片發(fā)送),另一端也回復(fù)關(guān)閉幀。關(guān)閉幀可攜帶數(shù)據(jù),攜帶的數(shù)據(jù)前兩個字節(jié)表示關(guān)閉狀態(tài)碼。連接正常關(guān)閉的狀態(tài)碼是1000。
通常關(guān)閉幀先由客戶端發(fā)起,服務(wù)器在回復(fù)關(guān)閉幀后就立即關(guān)閉 TCP 連接。如果關(guān)閉幀先由服務(wù)器發(fā)起,那么客戶端在回復(fù)關(guān)閉幀后要等待服務(wù)器先關(guān)閉 TCP 連接。
總結(jié)
以上是生活随笔為你收集整理的WebSocket 协议简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为何5G好像没比4G快?中国工程院院士答
- 下一篇: 英语语法入门十八(形容词的比较级和最高级