本篇文章主要講述以下幾點(diǎn):
- WebSocket的原理與機(jī)制
- WebSocket與Socket.io
- WebSocket兼容性
WebSocket的原理與機(jī)制
WebSocket協(xié)議分為兩部分:握手和數(shù)據(jù)傳輸
下面通過(guò)客戶端和服務(wù)端交互的報(bào)文對(duì)比WebSocket通訊與傳統(tǒng)HTTP的不同點(diǎn),主要關(guān)注握手階段。
根據(jù)上面的例子,運(yùn)行之后,new WebSocket實(shí)例化一個(gè)新的WebSocket客戶端對(duì)象,請(qǐng)求WebSocket URL為ws://localhost:8000的服務(wù)器,打開(kāi)控制臺(tái)的NetWork,客戶端WebSocket對(duì)象會(huì)自動(dòng)解析并識(shí)別為WebSocket請(qǐng)求,連接服務(wù)端端口,執(zhí)行雙方握手過(guò)程,來(lái)自客戶端握手發(fā)送數(shù)據(jù)格式如下:

客戶端發(fā)起的WebSocket連接報(bào)文類似傳統(tǒng)HTTP報(bào)文,其中:
- Upgrade: websocket
Connection: Upgrade
這個(gè)是WebSocket的核心,告訴服務(wù)器,客戶端發(fā)起的是WebSocket類型請(qǐng)求。 - Sec-WebSocket-Key是WebSocket客戶端發(fā)送的一個(gè) base64編碼的密文,瀏覽器隨機(jī)生成,要求服務(wù)端必須返回一個(gè)對(duì)應(yīng)加密的Sec-WebSocket-Accept應(yīng)答,否則客戶端會(huì)拋出Error during WebSocket handshake錯(cuò)誤,并關(guān)閉連接。
- Sec-WebSocket-Version 是告訴服務(wù)器所使用的 Websocket 協(xié)議版本

- Upgrade: websocket
Connection: Upgrade
告訴客戶端即將升級(jí)的是WebSocket協(xié)議 - Sec-WebSocket-Accept的值是服務(wù)端采用與客戶端一致的密鑰計(jì)算出來(lái)后返回客戶端的
至此,HTTP已經(jīng)完成它所有工作,接下來(lái)就是完全按照Websocket協(xié)議進(jìn)行了。
通過(guò)查看WebSocket的原理,與HTTP對(duì)比,得出結(jié)論:
HTTP長(zhǎng)連接中,每次數(shù)據(jù)交換除了真正的數(shù)據(jù)部分外,服務(wù)器和客戶端還要大量交換HTTP header,信息交換效率很低。Websocket協(xié)議通過(guò)第一個(gè)請(qǐng)求建立了TCP連接之后,之后交換的數(shù)據(jù)都不需要發(fā)送 HTTP header就能交換數(shù)據(jù),這顯然和原有的HTTP協(xié)議有區(qū)別,所以它需要對(duì)服務(wù)器和客戶端都進(jìn)行升級(jí)才能實(shí)現(xiàn)(主流瀏覽器都已支持HTML5)。此外還有 multiplexing、不同的URL可以復(fù)用同一個(gè)WebSocket連接等功能。這些都是HTTP長(zhǎng)連接不能做到的。
WebSocket與Socket.io
我們?cè)谑褂肳ebSocket協(xié)議時(shí)通常不會(huì)使用它的API來(lái)實(shí)現(xiàn),而是借助于Socket.io,Socket.io是一個(gè)WebSocket庫(kù),包括客戶端的js和服務(wù)端的nodejs,它的目標(biāo)是構(gòu)建可以在不同瀏覽器和移動(dòng)設(shè)備上使用的實(shí)時(shí)應(yīng)用。它會(huì)自動(dòng)根據(jù)瀏覽器從WebSocket、AJAX長(zhǎng)輪詢等各種方式中選擇最佳的方式來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)實(shí)時(shí)應(yīng)用,也就是說(shuō)如果瀏覽器對(duì)WebSocket兼容性差,Socket.io會(huì)自動(dòng)選擇最佳方式實(shí)現(xiàn)實(shí)時(shí)通信,非常方便和人性化。
Socket.io官方文檔:https://socket.io/get-started/chat/
WebSocket兼容性
WebSocket兼容幾乎所有現(xiàn)代瀏覽器,IE 10+ Edge Firefox 4+ Chrome 4+ Safari 5+ Opera 11.5+
socket.io對(duì)瀏覽器做了很好的兼容。
下一篇講述Socket.io客戶端API