webSocket建立連接的過(guò)程:
瀏覽器先發(fā)送http報(bào)文,借用了http協(xié)議來(lái)完成一部分握手,這個(gè)http報(bào)文中有這么一段信息"Upgrade:websocket",這是告訴服務(wù)器"你好,我要切換協(xié)議"。服務(wù)器接收后,回復(fù)一個(gè)http報(bào)文,告訴瀏覽器"好的,我已經(jīng)切換到websocket協(xié)議了"。從這里以后就不用http報(bào)文了,接下來(lái)就完全按照websocket協(xié)議進(jìn)行了。
1. 為什么需要 WebSocket
我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個(gè)協(xié)議?它能帶來(lái)什么好處?
答案:因?yàn)?HTTP 協(xié)議有一個(gè)缺陷:通信只能由客戶(hù)端發(fā)起。這種單向請(qǐng)求的特點(diǎn),注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶(hù)端要獲知就非常麻煩。我們只能使用"輪詢(xún)":每隔一段時(shí)候,就發(fā)出一個(gè)詢(xún)問(wèn),了解服務(wù)器有沒(méi)有新的信息。最典型的場(chǎng)景就是聊天室。
2. 簡(jiǎn)介
WebSocket 協(xié)議在2008年誕生,2011年成為國(guó)際標(biāo)準(zhǔn)。所有瀏覽器都已經(jīng)支持了。
它的最大特點(diǎn)就是,服務(wù)器可以主動(dòng)向客戶(hù)端推送信息,客戶(hù)端也可以主動(dòng)向服務(wù)器發(fā)送信息,是真正的雙向平等對(duì)話。
其他特點(diǎn)包括:
(1)建立在 TCP 協(xié)議之上,服務(wù)器端的實(shí)現(xiàn)比較容易。
(2)與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時(shí)不容易屏蔽,能通過(guò)各種 HTTP 代理服務(wù)器。
(3)數(shù)據(jù)格式比較輕量,性能開(kāi)銷(xiāo)小,通信高效。
(4)可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)。
(5)沒(méi)有同源限制,客戶(hù)端可以與任意服務(wù)器通信。
(6)協(xié)議標(biāo)識(shí)符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL。
ws://example.com:80/some/path
3. 客戶(hù)端的簡(jiǎn)單示例
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
4. 客戶(hù)端的 API
4.1 WebSocket 構(gòu)造函數(shù)
const ws = new WebSocket('ws://localhost:8080');
執(zhí)行上面語(yǔ)句之后,客戶(hù)端就會(huì)與服務(wù)器進(jìn)行連接。
4.2 webSocket.readyState
readyState屬性返回實(shí)例對(duì)象的當(dāng)前狀態(tài),共有四種。
- CONNECTING:值為0,表示正在連接。
- OPEN:值為1,表示連接成功,可以通信了。
- CLOSING:值為2,表示連接正在關(guān)閉。
- CLOSED:值為3,表示連接已經(jīng)關(guān)閉,或者打開(kāi)連接失敗。