websocket協(xié)議簡(jiǎn)析

websocket協(xié)議是基于tcp的網(wǎng)絡(luò)協(xié)議,實(shí)現(xiàn)了瀏覽器與客戶端的全雙工通信,與http協(xié)議不同的是,它允許服務(wù)器主動(dòng)推送消息給客戶端。這樣便可以取代原來(lái)低效的輪詢。

背景

在websocket出現(xiàn)之前,客戶端獲取服務(wù)器消息,需要通過(guò)不停的輪詢。有如下缺陷:

1)服務(wù)器被迫為每個(gè)客戶端使用許多不同的底層TCP連接:一個(gè)用于向客戶端發(fā)送信息,其它用于接收每個(gè)傳入消息。

2)http協(xié)議有額外的開(kāi)銷,每個(gè)消息都有HTTP頭。

3)客戶端需要通過(guò)映射來(lái)維護(hù)傳出連接和傳人連接用以追蹤響應(yīng)。

Websocket協(xié)議的出現(xiàn)正是彌補(bǔ)了上述缺陷,實(shí)現(xiàn)全雙工通信,允許服務(wù)器主動(dòng)推送消息給客戶端。

協(xié)議分析

websocket協(xié)議分為兩部分,一是握手建立連接;二是數(shù)據(jù)傳輸。

建立連接;

websocket的連接建立是基于http協(xié)議的。

請(qǐng)求報(bào)文示例:

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

響應(yīng)報(bào)文示例:

HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Sec-WebSocket-Protocol: chat

下面來(lái)分析一下上述報(bào)文:

WebSocket借用http請(qǐng)求進(jìn)行握手,相比正常的http請(qǐng)求,多了一些內(nèi)容。其中,

HTTP/1.1 101表示websocket連接已成功建立,其他任何code表示連接建立失敗。

Upgrade: websocket

Connection: Upgrade

表示希望將http協(xié)議升級(jí)到Websocket協(xié)議。

Sec-WebSocket-Key是瀏覽器隨機(jī)生成的base64 encode的值,用來(lái)詢問(wèn)服務(wù)器是否是支持WebSocket。

服務(wù)器返回

Upgrade: websocket

Connection: Upgrade

告訴瀏覽器即將升級(jí)的是Websocket協(xié)議

Sec-WebSocket-Accept是將請(qǐng)求包"Sec-WebSocket-Key"的值,與"258EAFA5-E914-47DA-95CA-C5AB0DC85B11″這個(gè)字符串進(jìn)行拼接,然后對(duì)拼接后的字符串進(jìn)行sha-1運(yùn)算,再進(jìn)行base64編碼得到的。用來(lái)說(shuō)明自己是WebSocket助理服務(wù)器。

Sec-WebSocket-Version是WebSocket協(xié)議版本號(hào)。

若請(qǐng)求報(bào)文中,Sec-WebSocket-Version: 25,服務(wù)端可能的響應(yīng)會(huì)是

HTTP/1.1 400 Bad Request ... Sec-WebSocket-Version: 13, 8, 7

此時(shí)客戶端將會(huì)重新進(jìn)行握手,并將版本修改為 Sec-WebSocket-Version: 13

數(shù)據(jù)傳輸:

websocket協(xié)議中數(shù)據(jù)是通過(guò)一系列的幀來(lái)傳輸。出于安全性考慮,所有客戶端發(fā)往服務(wù)器的數(shù)據(jù)幀需要掩碼,若服務(wù)器收到未掩碼的數(shù)據(jù)幀將會(huì)主動(dòng)斷開(kāi)連接;所有服務(wù)器發(fā)往客戶端的數(shù)據(jù)幀不能掩碼,若客戶端收到掩碼的數(shù)據(jù)幀將會(huì)主斷開(kāi)連接。

數(shù)據(jù)幀的定義:


FIN: 1 bit --是否是消息的最后一個(gè)數(shù)據(jù)幀。一個(gè)消息可以通過(guò)一個(gè)或多個(gè)數(shù)據(jù)幀發(fā)送,第一個(gè)幀也可能是最后一個(gè)幀。

RSV1, RSV2, RSV3: 1 bit each-- 保留字段,如果有自定義的擴(kuò)展數(shù)據(jù)時(shí)使用。當(dāng)沒(méi)有擴(kuò)展數(shù)據(jù)時(shí),若保留字段非0,則會(huì)導(dǎo)致連接失敗。

Opcode: 4 bits--說(shuō)明數(shù)據(jù)的類型。eg:%x1表示文本幀;%x2表示二進(jìn)制幀;%x8表示關(guān)閉連接幀;%x9表示ping幀;%xA 表示 pong幀。從此可以看出,目前websocket支持的傳輸類型包含文本,二進(jìn)制和ping/pong。

Mask: 1 bit--是否掩碼。(規(guī)則上文已述)

Payload length: 7 bits, 7+16 bits, or 7+64 bits--數(shù)據(jù)長(zhǎng)度

Masking-key: 0 or 4 bytes--掩碼的key(若mask is 1)

Payload data: (x+y) bytes-- 數(shù)據(jù),包含擴(kuò)展數(shù)據(jù)和應(yīng)用數(shù)據(jù)。

Extension data: x bytes--私有定制協(xié)議。

Application data: y bytes--傳輸?shù)臄?shù)據(jù)

示例

o 非掩碼的Hello: * 0x81 0x05 0x48 0x65 0x6c 0x6c 0x6f

注解:

0x81 -->10000001

-->Fin=1(最后幀);RSV=000;Opcode=0001(文本幀)

0x05 -->00000101

--> mask=0(不掩碼);Payload length=0000101(5個(gè)字符)

0x48 0x65 0x6c 0x6c 0x6f -->Hello

o掩碼的Hello: * 0x81 0x85 0x37 0xfa 0x21 0x3d 0x7f 0x9f 0x4d 0x51 0x58 (contains "Hello")

o多幀不掩碼的Hello * 0x01 0x03 0x48 0x65 0x6c (contains "Hel")

0x80 0x02 0x6c 0x6f (contains "lo")

256字節(jié)二進(jìn)制非掩碼數(shù)據(jù)* 0x82 0x7E 0x0100 [256 bytes of binary data]

64KiB單幀二進(jìn)制非掩碼數(shù)據(jù)

0x82 0x7F 0x0000000000010000 [65536 bytes of binary data]

數(shù)據(jù)發(fā)送規(guī)則:

1)保證連接狀態(tài)為open。

2)不知大小或太大的數(shù)據(jù),會(huì)分為一系列的幀來(lái)發(fā)送。

3)數(shù)據(jù)發(fā)送幀中必須標(biāo)明數(shù)據(jù)類型

4)最后一個(gè)數(shù)據(jù)幀必須將Fin設(shè)置為1

5)客戶端發(fā)送的數(shù)據(jù)必須掩碼

6)擴(kuò)展數(shù)據(jù)必須有定義

7)數(shù)據(jù)必須通過(guò)下行連接發(fā)送。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 上篇介紹了HTTP1.1協(xié)議的基本內(nèi)容,這篇文章將繼續(xù)分析WebSocket協(xié)議,然后對(duì)這兩個(gè)進(jìn)行簡(jiǎn)單的比較。 W...
    TheAlchemist閱讀 36,931評(píng)論 15 113
  • Before them people believedAristotle, who said that the n...
    咩咩咩233閱讀 307評(píng)論 0 0
  • 夜來(lái)幽夢(mèng)忽還鄉(xiāng) 小軒窗,正梳妝 相顧無(wú)言,唯有淚千行 好神奇,我一直都很喜歡這首悼亡的詞,其后看到再多的春風(fēng)十里不...
    守望清橙閱讀 381評(píng)論 4 8
  • 很多健身菜鳥(niǎo)或者想增肌、減脂的人,剛踏入健身房或者剛開(kāi)始鍛煉的時(shí)候,腦袋里好像裝了一本《十萬(wàn)個(gè)為什么》,經(jīng)常會(huì)問(wèn)一...
    桃白白ALEX閱讀 817評(píng)論 0 1

友情鏈接更多精彩內(nèi)容