webSocket建立連接的過程:
瀏覽器先發(fā)送http報文鲜戒,借用了http協(xié)議來完成一部分握手焚虱,這個http報文中有這么一段信息"Upgrade:websocket"堰燎,這是告訴服務(wù)器"你好楣责,我要切換協(xié)議"聚磺。服務(wù)器接收后坯台,回復(fù)一個http報文,告訴瀏覽器"好的咧最,我已經(jīng)切換到websocket協(xié)議了"捂人。從這里以后就不用http報文了,接下來就完全按照websocket協(xié)議進(jìn)行了矢沿。
1. 為什么需要 WebSocket
我們已經(jīng)有了 HTTP 協(xié)議滥搭,為什么還需要另一個協(xié)議?它能帶來什么好處捣鲸?
答案:因為 HTTP 協(xié)議有一個缺陷:通信只能由客戶端發(fā)起瑟匆。這種單向請求的特點,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化栽惶,客戶端要獲知就非常麻煩愁溜。我們只能使用"輪詢":每隔一段時候,就發(fā)出一個詢問外厂,了解服務(wù)器有沒有新的信息冕象。最典型的場景就是聊天室。
2. 簡介
WebSocket
協(xié)議在2008年誕生汁蝶,2011年成為國際標(biāo)準(zhǔn)渐扮。所有瀏覽器都已經(jīng)支持了。
它的最大特點就是掖棉,服務(wù)器可以主動向客戶端推送信息墓律,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話幔亥。
其他特點包括:
(1)建立在 TCP 協(xié)議之上耻讽,服務(wù)器端的實現(xiàn)比較容易。
(2)與 HTTP 協(xié)議有著良好的兼容性帕棉。默認(rèn)端口也是80和443针肥,并且握手階段采用 HTTP 協(xié)議饼记,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器祖驱。
(3)數(shù)據(jù)格式比較輕量握恳,性能開銷小,通信高效捺僻。
(4)可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)崇裁。
(5)沒有同源限制匕坯,客戶端可以與任意服務(wù)器通信。
(6)協(xié)議標(biāo)識符是ws(如果加密拔稳,則為wss)葛峻,服務(wù)器網(wǎng)址就是 URL。
ws://example.com:80/some/path
3. 客戶端的簡單示例
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. 客戶端的 API
4.1 WebSocket 構(gòu)造函數(shù)
const ws = new WebSocket('ws://localhost:8080');
執(zhí)行上面語句之后巴比,客戶端就會與服務(wù)器進(jìn)行連接术奖。
4.2 webSocket.readyState
readyState
屬性返回實例對象的當(dāng)前狀態(tài),共有四種轻绞。
- CONNECTING:值為0采记,表示正在連接。
- OPEN:值為1政勃,表示連接成功唧龄,可以通信了。
- CLOSING:值為2奸远,表示連接正在關(guān)閉既棺。
- CLOSED:值為3,表示連接已經(jīng)關(guān)閉懒叛,或者打開連接失敗丸冕。