摘要:概述本文是系列的第一篇,主要介紹相關的基礎協議知識和。客戶端收到響應后,立即發起下一次的請求。收到消息通過事件來接收消息。類型則需要傳遞一個對象作為參數,相關的內容也將在本系列第二篇中進行介紹。
概述
本文是WebSocket系列的第一篇,主要介紹WebSocket相關的基礎協議知識和API。由于WebSocket的相關介紹在MDN中分布較亂,初學者不太容易入門,因此通過本文將相關基礎知識和使用方法進行一個歸納和總結。
本文主要內容如下:
WebSocket基礎概念介紹
WebSocket協議初讀
WebSocket 相關API淺析
WebSocket在線上項目中的使用
通過本文,你能夠了解到WebSocket相關基礎知識,同時了解到WebSocket在線上環境中是如何使用的。
WebSocket介紹WebSockets 是一個可以創建和服務器間進行雙向會話的高級技術。通過這個API你可以向服務器發送消息并接受基于事件驅動的響應,這樣就不用向服務器輪詢獲取數據了。
上面是MDN中關于WebSocket的說明。其中雙向會話指的是客戶端和服務端都能夠通過WebSocket來進行數據的互相傳遞,即服務端可以給客戶端推送數據,客戶端也可以通過WebSocket來傳遞數據。
為什么要使用WebSocket在不使用WebSocket時,如果我們需要建立一條長連接,有以下幾種方法:
輪詢
長輪詢(常用)
SSE(Server Send Event)
下面,我們對這幾個都進行簡單的介紹。
輪詢輪詢是最早在客戶端用來模擬長連接的一種方式。他通過客戶端定時想服務端發送HTTP請求來模擬客戶端向服務端發送數據,而服務端的數據則是在客戶端發送HTTP請求后跟隨返回。
這種方案能夠讓客戶端的數據幾乎實時的到達,但是缺點也顯而易見:服務端的數據需要在客戶端的請求回來后才能帶回。如果HTTP請求的間隔太短,則會導致大量的網絡開銷;如果間隔太長,這將導致數據傳遞的不及時。
長輪詢長輪詢是在輪詢的基礎上改進的一種方式。在客戶端發送HTTP請求且服務端收到請求時,服務端會先維持這個請求不返回。在特定的時間內(一般為30秒,因為通常HTTP判斷超時時間為30秒),如果服務端沒有數據,則回應這個請求;服務端有數據需要發送時,則立即通過HTTP請求的響應將數據傳遞給客戶端。客戶端收到響應后,立即發起下一次的HTTP請求。
這種方案能夠解決輪詢中帶來的服務端數據不能及時傳遞的問題,但是帶來的網絡花銷大的問題仍然無法解決。
SSE(Server Send Event)SSE是一個新的協議,作用為服務端想客戶端推送數據。他通過自定義的SSE協議來實現單項的數據推送。SSE的缺點是數據只能從服務端像客戶端傳遞,而數據不能通過客戶端向服務端傳遞。
WebSocket能夠解決上述問題WebSocket能夠有效的解決以下問題:
帶寬問題:WebSocket相對于HTTP來說協議頭更加小,同時按需傳遞。
數據實時性問題:WebSocket相對于輪詢和長輪詢來說,能夠實時傳遞數據,延遲更小。
狀態問題:相較于HTTP的無狀態請求,WebSocket在建立連接后能夠維持特定的狀態。
其他的優點可以參考維基百科。
WebSocket協議了解了為什么需要使用WebSocket,下面讓我們來了解下WebSocket協議相關的內容。
WebSocket協議是通過HTTP協議升級而來。只需要在HTTP協議基礎上增加兩次握手,即可建立WebSocket連接(如果是需要通過SSL加密,則還需要進行SSL握手過程),握手的部分詳情可以見WebSocket文檔,下面我們簡單介紹以下Header相關字段。
請求Header請求Header如下:
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
其中:
Host: server.example.com:表示將要連接的WebSocket地址。
Connection: Upgrade:需要升級HTTP連接。
Upgrade: websocket:將HTTP連接升級至WebSocket連接。
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ== :客戶端生成的WebSocket連接密鑰。
Sec-WebSocket-Protocol: chat, superchat:指定哪些協議是客戶端可以接受的。
Sec-WebSocket-Version: 13:WebSocket版本號。
響應HeaderHTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
其中:
Upgrade: websocket:確認將HTTP連接升級至WebSocket連接。
Connection: Upgrade:確認升級HTTP連接。
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo:服務端根據客戶端的連接密鑰生成的服務端密鑰。
Sec-WebSocket-Protocol: chat:選擇的WebSocket協議。
WebSocket API介紹對WebSocket的協議有了一個初步的了解,下面讓我們看下,在具體的使用場景中,如何使用WebSocket。
WebSocket的API不多,下面我們就根據使用的順序:
建立連接
收到消息
發送消息
關閉連接
來逐一進行介紹,具體的MDN資料可以見此處。
建立連接WebSocket通過初始化實例來建立連接,通過open事件回調函數來確認連接建立成功,具體示例如下:
const webSocket = new WebSocket("ws://server.example.com"); webSocket.addEventListener("open", (event) => { // 建立連接成功 });
在WebSocket建立ws連接時,url可以是域名或者IP地址;但是當建立的連接是wss(加密WebSocket)時,url必須是域名,因為需要配置相應的證書,而證書是針對域名的。
收到消息WebSocket通過message事件來接收消息。
socket.addEventListener("message", function (event) { console.log("Message from server", event.data); });
WebSocket可以傳遞String、ArrayBuffer和Blob三種數據類型,因此在收到消息時可能是其中的任意一種。其中,String和ArrayBuffer使用的最多。
如果是String類型,直接通過字符串處理函數即可進行相關轉換,如JSON等格式。
如果是二進制blob類型,則需要使用ArrayBuffer和DataView來進行處理,相關的內容將在本系列第二篇中進行介紹。
發送消息WebSocket通過send方法來發送消息。
webSocket.send(data);
示例中的data字段,也有可能是收到消息所說的String、ArrayBuffer和Blob三種數據類型之一。
String類型只需要傳遞一個字符串給send方法作為參數即可。
ArrayBuffer類型則需要傳遞一個ArrayBuffer對象作為參數,相關的內容也將在本系列第二篇中進行介紹。
關閉連接 被動關閉當服務端主動關閉WebSocket連接時,會通過WebSocket向客戶端發送一個close數據包,WebSocket的close事件會觸發。
webSocket.addEventListener("close", (closeEvent) => { });
注:當網絡斷開時,WebSocket連接并不會被動關閉,因為沒有收到關閉的數據包。
主動關閉客戶端可以通過WebSocket提供的close方法來主動關閉長連接。
webSocket.close();
目前該方法有兩個參數(在某些版本中不支持,詳情見MDN文檔)):
第一個參數表示關閉連接的狀態號,默認為1000,表示正常關閉。
第二個參數為關閉原因,是一個不長于123字節的UTF-8文本。
總結本文主要是介紹了一下WebSocket相關的基礎知識。
通過WebSocket的長連接,客戶端和服務端可以進行大量的數據傳輸而不會帶來相關的性能問題,這給Web端帶來了極大的功能增強。目前Web端可以使用WebSocket來進行IM相關功能開發,或者實時協作等需要與服務端進行大量數據交互的功能,并且不需要像之前一樣使用長輪詢的Hack方式來實現。
具體的使用方式和線上的使用問題,將會在本系列后幾篇博客中進行介紹。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93738.html
摘要:本文作為系列的第四篇內容,將會用一個簡單的聊天應用把整個傳輸二進制數據類型的內容連接起來,讓用戶對整個傳輸二進制數據的方法有個了解。如何發送二進制數據通過如何設計一個二進制協議一章,我們知道了如何定義傳輸的二進制數據格式。 概述 通過前三篇博客,我們能夠了解在通過WebSocket發送數據之前,我們需要傳遞的數據是如何變成ArrayBuffer二進制數據的;在我們收到二進制數據之后,我...
摘要:與此同時,后端服務的中也有相關的長連接維持時長設置。如何快速的恢復連接根據上面的操作方案,我們會在網絡異常時斷開連接。 概述 通過前四篇博客,相信讀者對于WebSocket的使用和數據(不論是ArrayBuffer還是String)傳輸都有了一個深刻的了解。現在我們來介紹下,我在使用WebSocket時,連接相關模塊遇到的一些共性問題,以及我們如何解決這些問題。 本文作為WebSock...
摘要:總結通過使用和,我們能夠在數據和二進制數據中進行互相轉換。下一篇系列相關的博客,將會介紹如何通過來向后端傳遞二進制數據,以及如何處理通過收到的二進制數據。 概述 上一篇博客我們說到了如何進行數字類型(如Short、Int、Long類型)如何在JavaScript中進行二進制轉換,如果感興趣的可以可以閱讀本系列第二篇博客——WebSocket系列之JavaScript中數字數據如何轉換為...
摘要:以和為例,說明中的數字數據如何轉換為二進制數據。對象用來表示通用的固定長度的原始二進制數據緩沖區。中的數字數據如何轉換為二進制數據對和有了一個大概的了解,下面讓我們來看下它是如何進行二進制數據操作的。 概述 本文主要通過對JavaScript中數字數據與二進制數據之間的轉換,讓讀者能夠了解在JavaScript中如何對數字類型(包括但不限于Number類型)進行處理。 二進制數據在日常...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
閱讀 3471·2023-04-25 18:52
閱讀 2484·2021-11-22 15:31
閱讀 1224·2021-10-22 09:54
閱讀 3010·2021-09-29 09:42
閱讀 605·2021-09-26 09:55
閱讀 909·2021-09-13 10:28
閱讀 1098·2019-08-30 15:56
閱讀 2107·2019-08-30 15:55