日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

作者:wzhvictor
來(lái)源:https://segmentfault.com/a/1190000014643900

 

什么是 WebSocket ?

WebSocket 是一種標(biāo)準(zhǔn)協(xié)議,用于在客戶端和服務(wù)端之間進(jìn)行雙向數(shù)據(jù)傳輸。但它跟 HTTP 沒(méi)什么關(guān)系,它是基于 TCP 的一種獨(dú)立實(shí)現(xiàn)。

以前客戶端想知道服務(wù)端的處理進(jìn)度,要不停地使用 Ajax 進(jìn)行輪詢,讓瀏覽器隔個(gè)幾秒就向服務(wù)器發(fā)一次請(qǐng)求,這對(duì)服務(wù)器壓力較大。另外一種輪詢就是采用 long poll 的方式,這就跟打電話差不多,沒(méi)收到消息就一直不掛電話,也就是說(shuō),客戶端發(fā)起連接后,如果沒(méi)消息,就一直不返回 Response 給客戶端,連接階段一直是阻塞的。

而 WebSocket 解決了 HTTP 的這幾個(gè)難題。當(dāng)服務(wù)器完成協(xié)議升級(jí)后( HTTP -> WebSocket ),服務(wù)端可以主動(dòng)推送信息給客戶端,解決了輪詢?cè)斐傻耐窖舆t問(wèn)題。由于 WebSocket 只需要一次 HTTP 握手,服務(wù)端就能一直與客戶端保持通信,直到關(guān)閉連接,這樣就解決了服務(wù)器需要反復(fù)解析 HTTP 協(xié)議,減少了資源的開銷。

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

隨著新標(biāo)準(zhǔn)的推進(jìn),WebSocket 已經(jīng)比較成熟了,并且各個(gè)主流瀏覽器對(duì) WebSocket 的支持情況比較好(不兼容低版本 IE,IE 10 以下),有空可以看看。

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

使用 WebSocket 的時(shí)候,前端使用是比較規(guī)范的,js 支持 ws 協(xié)議,感覺(jué)類似于一個(gè)輕度封裝的 Socket 協(xié)議,只是以前需要自己維護(hù) Socket 的連接,現(xiàn)在能夠以比較標(biāo)準(zhǔn)的方法來(lái)進(jìn)行。

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

 

下面我們就結(jié)合上圖具體來(lái)聊一下 WebSocket 的通信過(guò)程。

建立連接

客戶端請(qǐng)求報(bào)文 Header

客戶端請(qǐng)求報(bào)文:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

與傳統(tǒng) HTTP 報(bào)文不同的地方:

Upgrade: websocket
Connection: Upgrade

這兩行表示發(fā)起的是 WebSocket 協(xié)議。

Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 是由瀏覽器隨機(jī)生成的,提供基本的防護(hù),防止惡意或者無(wú)意的連接。

Sec-WebSocket-Version 表示 WebSocket 的版本,最初 WebSocket 協(xié)議太多,不同廠商都有自己的協(xié)議版本,不過(guò)現(xiàn)在已經(jīng)定下來(lái)了。如果服務(wù)端不支持該版本,需要返回一個(gè) Sec-WebSocket-Versionheader,里面包含服務(wù)端支持的版本號(hào)。

創(chuàng)建 WebSocket 對(duì)象:

var ws = new websocket("ws://127.0.0.1:8001");

ws 表示使用 WebSocket 協(xié)議,后面接地址及端口

完整的客戶端代碼:

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

服務(wù)端響應(yīng)報(bào)文 Header

首先我們來(lái)看看服務(wù)端的響應(yīng)報(bào)文:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

我們一行行來(lái)解釋

  • 首先,101 狀態(tài)碼表示服務(wù)器已經(jīng)理解了客戶端的請(qǐng)求,并將通過(guò) Upgrade 消息頭通知客戶端采用不同的協(xié)議來(lái)完成這個(gè)請(qǐng)求;
  • 然后,Sec-WebSocket-Accept 這個(gè)則是經(jīng)過(guò)服務(wù)器確認(rèn),并且加密過(guò)后的 Sec-WebSocket-Key;
  • 最后,Sec-WebSocket-Protocol 則是表示最終使用的協(xié)議。

Sec-WebSocket-Accept 的計(jì)算方法:

  • 將 Sec-WebSocket-Key 跟 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接;
  • 通過(guò) SHA1 計(jì)算出摘要,并轉(zhuǎn)成 base64 字符串。

注意:Sec-WebSocket-Key/Sec-WebSocket-Accept 的換算,只能帶來(lái)基本的保障,但連接是否安全、數(shù)據(jù)是否安全、客戶端 / 服務(wù)端是否合法的 ws 客戶端、ws 服務(wù)端,其實(shí)并沒(méi)有實(shí)際性的保證。

創(chuàng)建主線程,用于實(shí)現(xiàn)接受 WebSocket 建立請(qǐng)求:

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

進(jìn)行通信

服務(wù)端解析 WebSocket 報(bào)文

Server 端接收到 Client 發(fā)來(lái)的報(bào)文需要進(jìn)行解析

Client 包格式

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

 

1、FIN: 占 1bit

0:不是消息的最后一個(gè)分片

1:是消息的最后一個(gè)分片

2、RSV1, RSV2, RSV3:各占 1bit

一般情況下全為 0。當(dāng)客戶端、服務(wù)端協(xié)商采用 WebSocket 擴(kuò)展時(shí),這三個(gè)標(biāo)志位可以非0,且值的含義由擴(kuò)展進(jìn)行定義。如果出現(xiàn)非零的值,且并沒(méi)有采用 WebSocket 擴(kuò)展,連接出錯(cuò)。

3、Opcode: 4bit

  • %x0:表示一個(gè)延續(xù)幀。當(dāng) Opcode 為 0 時(shí),表示本次數(shù)據(jù)傳輸采用了數(shù)據(jù)分片,當(dāng)前收到的數(shù)據(jù)幀為其中一個(gè)數(shù)據(jù)分片;
  • %x1:表示這是一個(gè)文本幀(text frame);
  • %x2:表示這是一個(gè)二進(jìn)制幀(binary frame);
  • %x3-7:保留的操作代碼,用于后續(xù)定義的非控制幀;
  • %x8:表示連接斷開;
  • %x9:表示這是一個(gè)心跳請(qǐng)求(ping);
  • %xA:表示這是一個(gè)心跳響應(yīng)(pong);
  • %xB-F:保留的操作代碼,用于后續(xù)定義的控制幀。

4、Mask: 1bit

表示是否要對(duì)數(shù)據(jù)載荷進(jìn)行掩碼異或操作。

0:否

1:是

5、Payload length: 7bit or (7 + 16)bit or (7 + 64)bit

表示數(shù)據(jù)載荷的長(zhǎng)度

  • 0~126:數(shù)據(jù)的長(zhǎng)度等于該值;
  • 126:后續(xù) 2 個(gè)字節(jié)代表一個(gè) 16 位的無(wú)符號(hào)整數(shù),該無(wú)符號(hào)整數(shù)的值為數(shù)據(jù)的長(zhǎng)度;
  • 127:后續(xù) 8 個(gè)字節(jié)代表一個(gè) 64 位的無(wú)符號(hào)整數(shù)(最高位為 0),該無(wú)符號(hào)整數(shù)的值為數(shù)據(jù)的長(zhǎng)度。

6、Masking-key: 0 or 4bytes

  • 當(dāng) Mask 為 1,則攜帶了 4 字節(jié)的 Masking-key;
  • 當(dāng) Mask 為 0,則沒(méi)有 Masking-key。

掩碼算法:按位做循環(huán)異或運(yùn)算,先對(duì)該位的索引取模來(lái)獲得 Masking-key 中對(duì)應(yīng)的值 x,然后對(duì)該位與 x 做異或,從而得到真實(shí)的 byte 數(shù)據(jù)。

注意:掩碼的作用并不是為了防止數(shù)據(jù)泄密,而是為了防止早期版本的協(xié)議中存在的代理緩存污染攻擊(proxy cache poisoning attacks)等問(wèn)題。

7、Payload Data: 載荷數(shù)據(jù)

解析 WebSocket 報(bào)文代碼如下:

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

服務(wù)端發(fā)送 WebSocket 報(bào)文

返回時(shí)不攜帶掩碼,所以 Mask 位為 0,再按載荷數(shù)據(jù)的大小寫入長(zhǎng)度,最后寫入載荷數(shù)據(jù)。

struct 模塊解析

struct.pack(fmt, v1, v2, ...)

按照給定的格式 fmt,把數(shù)據(jù)封裝成字符串 ( 實(shí)際上是類似于 C 結(jié)構(gòu)體的字節(jié)流 )

struct 中支持的格式如下表:

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)


為了同 C 語(yǔ)言中的結(jié)構(gòu)體交換數(shù)據(jù),還要考慮有的 C 或 C++ 編譯器使用了字節(jié)對(duì)齊,通常是以 4 個(gè)字節(jié)為單位的 32 位系統(tǒng),故而 struct 根據(jù)本地機(jī)器字節(jié)順序轉(zhuǎn)換。可以用格式中的第一個(gè)字符來(lái)改變對(duì)齊方式,定義如下:

 

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

 

發(fā)送 WebSocket 報(bào)文代碼如下:

WebSocket 通信過(guò)程與實(shí)現(xiàn)

 

總結(jié)

沒(méi)有其他能像 WebSocket 一樣實(shí)現(xiàn)全雙工傳輸?shù)募夹g(shù)了,迄今為止,大部分開發(fā)者還是使用 Ajax 輪詢來(lái)實(shí)現(xiàn),但這是個(gè)不太優(yōu)雅的解決辦法,WebSocket 雖然用的人不多,可能是因?yàn)閰f(xié)議剛出來(lái)的時(shí)候有安全性的問(wèn)題以及兼容的瀏覽器比較少,但現(xiàn)在都有解決。如果你有這些需求可以考慮使用 WebSocket:

  • 多個(gè)用戶之間進(jìn)行交互;
  • 需要頻繁地向服務(wù)端請(qǐng)求更新數(shù)據(jù)。

比如彈幕、消息訂閱、多玩家游戲、協(xié)同編輯、股票基金實(shí)時(shí)報(bào)價(jià)、視頻會(huì)議、在線教育等需要高實(shí)時(shí)的場(chǎng)景。

分享到:
標(biāo)簽:WebSocket
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定