整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          淺淺的聊一下 WebSocket

          淺淺的聊一下 WebSocket

          一次看到 ws://wss:// 時候,感覺好高級啊,還有這種協議。

          Websocket 歷史

          WebSocket是在2008年6月誕生的1。經由IEFT標準化后,2009年chrome 4第一個提供了該標準支持,并默認啟用。于2011年由IEFT標準化為RFC 6455。

          現在的瀏覽器均已支持該標準。

          Websocket 出現的背景

          思考一下我們經常遇到的一種需求場景,要求在某個網頁下,網頁的內容可以實時更新。

          這種情況下,最大眾化的方式就是輪詢接口了,即通過定時器,定時請求接口,獲取到最新的信息后,將內容更新到頁面中,如下:

          setInterval(()=> {
            queryAPI().then(()=> update());
          }, 1000);
          

          但是我們知道,這種定時器的延時并不是很精確,而且加上接口的請求時延,實際時間可能不止代碼中所預先設定的時間長度,所以這種實時更新是偽實時更新。

          除此之外,還有一點可能會經常遇到,即,我們更新信息并總是要更新整個頁面上所有可以看到的信息,我們更關注一些經常變化的信息,比如狀態,狀態的信息可能大小只有幾個字節,但是我們輪詢接口拿到的信息卻是這個頁面的所有信息,大小自然不只幾個字節,但是除狀態以外的信息都可以視作是冗余的。

          我們實際只需要一個字段,而且即使后端提供只返回狀態的接口,但實際在一個請求中還要計算ip報文頭的大小,依舊是很占用帶寬的。

          輪詢這種解決方案目前依舊是非常流行,最新的輪詢技術是Comet,這種技術雖然可以實現雙向通信,但仍然需要反復發出請求。而且在Comet中普遍采用的HTTP長連接也會消耗服務器資源2。

          Websocket通信模式

          了解網絡的都知道,數據傳輸分為單工、半雙工、全雙工三種工作模式。

          Websocket是基于TCP的,使用全雙工通信模式的協議,他使得客戶端和服務端之間的數據交換變得更簡單。而且,作為一個工作在全雙工模式下的協議,服務端可以在建立連接后隨時向客戶端推送消息。

          由于協議是基于TCP的,所以websocket也是需要建連和關閉連接的,但要注意的是,一般在websocket的握手通常指的是:客戶端發送一個http請求到服務端,服務端響應后標志這個鏈接建立起來。而不是指tcp的三次握手。

          另外在RFC 6455 1.1節「Background」中介紹:WebSocket通過HTTP端口的80和443進行工作,并支持HTTP代理和中介。

          原文:it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries

          為了實現和HTTP的兼容性,WebSocket握手使用HTTP的Upgrade頭將HTTP協議轉換成Websocket協議。

          作為一種協議,websocket自然也是有其用于協議控制的頭部信息的,但是相對于HTTP請求每次都要帶上完整的頭部信息,傳輸數據時,websocket數據包的頭部信息就相對較小,從而降低了控制開銷。

          相對于前文所提到的輪詢接口,websocket可以做到服務端直接向客戶端傳輸數據,省去了客戶端發起請求的步驟,同時沒有間隔時間,只要服務端內容變化,就可以告知客戶端,實時性上有了很大的提高。

          Websocket 使用

          WebSocket使用十分簡單,只需要關注以下API:

          1. WebSocket(url[, protocol]) 構造函數

          使用 new WebSocket(xxx) 創建對象時,會同時建立與服務器的連接

          1. WebSocket.onopen , WebSocket.onclose

          分別對應連接成功、失敗時的回調,這里可以做一些初始化、銷毀的工作

          1. WebSocket.onmessage

          實際處理數據是用的該函數

          在數據處理完成后,需要移除回調函數,不然可能會影響到其他地方的處理

          const ws=new WebSocket('ws://sdf.com');
          function handleData(evt) {
            // handle server data.
          }
          ws.onmessage=handleData;
          ws.addEventListener('message', handleData);
          
          1. WebSocket.send

          主動向服務端發送消息,可以通過send和onmessage進行數據互動,如:

          ws.send('list');
          
          ws.onmessage=evt=> {
            const data=evt.data;
            if (data==='hello') {
              console.log('world');
              return ;
            }
            try {
              const obj=JSON.parse(data);
              switch (obj.type) {
                case 'list':
                  // do something.
              }
            } catch (ex) {}
          }
          
          1. WebSocket.close

          關閉連接

          Node服務端的實現,這個就參考相關的庫吧,比較復雜。

          衍生知識

          http協議至今,主要經歷了三個版本。

          • http1.0 短連接,單工通信
            • http/1.0默認的模型是短連接,每個HTTP請求都由他自己獨立完成,下圖左1,可以看到每一個http請求都對應了一個建立連接關閉連接的階段,每一個請求都有TCP握手和揮手的階段。
            • 在這個模型下,想要做到實時更新頁面數據,只能考慮輪詢。
          • http1.1 支持長鏈接,半雙工通信
            • 1.0之后的版本,1.1會讓某個連接保持一定的時間,在這段時間里重復發送一系列請求(下圖左2),就是保活。
          • http2.0 支持多路復用,全雙工通信

          來源:https://www.cnblogs.com/keepsmart/p/16007094.html

          ebSocket

          • WebSocket 是一種支持雙向通訊網絡通信協議。
          • 意思就是服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息
          • 屬于服務器推送技術的一種.

          特點:

          (1)建立在 TCP 協議之上,服務器端的實現比較容易。

          (2)與 HTTP 協議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器。

          (3)數據格式比較輕量,性能開銷小,通信高效。

          (4)可以發送文本,也可以發送二進制數據(blob對象或Arraybuffer對象)

          (5)收到的數據類型 可以使用binaryType 指定, 顯示指定收到的二進制數據類型

          (6)沒有同源限制,客戶端可以與任意服務器通信。

          (7)協議標識符是ws(握手http)(如果加密,則為wss(tcp +TLS)),服務器網址就是 URL。

          WebSocket對象

          WebSocket對象提供了用于創建和管理WebSocket 連接,以及可以通過該連接發送和接收數據的 API。

          使用 WebSocket() 構造函數來構造一個 WebSocket 。

          為什么需要websocket

          Hypertext Transfer Protocol (HTTP) 協議

          一種無狀態的、應用層的、以請求/應答方式運行的協議,它使用可擴展的語義和自描述消息格式,與基于網絡的超文本信息系統靈活的互動.

          • 因為http 通信只能由客戶端發起,服務器返回查詢結果,HTTP 協議做不到服務器主動向客戶端推送信息, 服務器有連續的狀態變化,客戶端要獲知就非常麻煩。
          • 我們只能使用輪詢:每隔一段時候,就發出一個詢問,了解服務器有沒有新的信息。最典型的場景就是聊天室。
          • 輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開);

          Chrome 請求列表:分析 WebSocket

          過濾器(過濾資源xhr js ws css ws等):

          • 按照類型: ws
          • 屬性過濾: is:running

          表格列 Frames

          Data: 消息負載。 如果消息為純文本,直接顯示。 二進制操作嗎顯示操作碼名稱和代碼(Continuation Frame、 Binanry Frame、 Connection Close Frame、 Ping Frame或者Pong Frame)
          Length: 消息負載的長度 以字節為單位
          Time: 收到或者發送的時間。

          消息顏色

          • 發送到服務器的文本消息為淺綠色
          • 接收到的文本消息為白色
          • WebSocket 操作碼 為淺黃色
          • 錯誤為淺紅色

          WbeSocket 的成本 對比http

          1、實時性與可伸縮性。 犧牲了簡單性。

          2、網絡效率與無狀態: 請求1基于請求2 犧牲了簡單性與可見性

          websocket 的心跳保持 對比http

          • (http 長連接只能基于簡單的超時(常見為65s))
          • websocket 鏈接基于ping/pong 心跳機制維持

          設計哲學: 在web約束下暴露tcp 給上層

          元數據

          • http 協議頭部會存放元數據.
          • websocket 上傳輸的應用層存放元數據

          基于幀: 不是基于字節流(http, tcp)

          • 每一幀要么存放字符數據,要么承載二進制數據

          基于瀏覽器的同源策略模型個(非瀏覽器無效)

          可以使用Access-Control-Allow-Origin 等頭部

          基于URI、子協議支持同主機``同端口上的多個服務

          幀格式示意圖

          ABNF 描述的幀格式

          ini

          復制代碼

          ws-frame=frame-fin ; 1 bit in length frame-rsv1 ; 1 bit in length frame-rsv2 ; 1 bit in length frame-rsv3 ; 1 bit in length frame-opcode ; 4 bits in length frame-masked ; 1 bit in length frame-payload-length ; 3 種長度 [ frame-masking-key ] ; 32 bits in length frame-payload-data ; n*8 bits in ; length, where ; n >=0

          紅色: 2 字節必然存在的幀首部

          數據幀格式: Rsv 保留值

          RSV1/RSV2/RSV3:默認為 0,僅當使用 extension 擴展時,由擴展決定其值

          數據幀格式:幀類型

          • 持續幀
            0: 繼續前一幀
          • 非控制幀
            1: 文本幀(utf-8)
            2:二進制幀
            3-7: 為非控制幀保留
          • 控制幀 8: 關閉幀 9: 心跳幀ping A: 心跳幀pong B-F:控制幀保留

          URI 格式

          1、ws-uri: ws://[host][:port][path][?query]
          端口port默認 80
          2、wss-uri: wss://[host][:port][path][?query] 端口port 默認443

          客戶端提供信息

          host、port 主機端口
          schema: 是否基于SSL
          訪問的資源:uri
          握手隨機數:Sec-WebSocket-Key
          選擇的子協議:Sec-WebSocket-Protocol
          擴展協議:Sec-WebSocket-Extensions
          CORS:Origin

          如何證明握手被服務器接受?預防意外

          請求中的 Sec-WebSocket-Key 隨機數

          Sec-WebSocket-Key: A1EEou7Nnq6+BBZoAZqWlg==

          響應中的 Sec-WebSocket-Accept 證明值

          GUID(RFC4122):258EAFA5-E914-47DA-95CA-C5AB0DC85B11

          ? 值構造規則:BASE64(SHA1(Sec-WebSocket-Key + GUID))

          ? 拼接值:A1EEou7Nnq6+BBZoAZqWlg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11

          ? SHA1 值:713f15ece2218612fcadb1598281a35380d1790f

          ? BASE 64 值:cT8V7OIhhhL8rbFZgoGjU4DReQ8=

          ? 最終頭部:Sec-WebSocket-Accept: cT8V7OIhhhL8rbFZgoGjU4DReQ8=


          作者:LHDIYU
          鏈接:https://juejin.cn/post/6989539483695710215
          來源:稀土掘金
          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

          WebSocket 作為一種基于 TCP 協議的實時通信協議,為前端應用提供了強大的雙向通信能力。本文將深入探討前端 WebSocket 的相關問題,包括協議區別、用法、關鍵技術點等。

          WebSocket 協議和 HTTP 協議的區別是什么?

          WebSocket 是一種實時雙向通信協議,與 HTTP 協議相比,有以下幾個主要區別:

          • 連接方式:WebSocket 提供持久的連接,通過握手過程建立連接后保持打開狀態,而 HTTP 是無狀態的,每次請求都需要重新建立連接。
          • 數據格式:WebSocket 支持文本和二進制數據的傳輸,而 HTTP 主要是傳輸文本數據。
          • 數據傳輸方式:WebSocket 實現了全雙工通信,客戶端和服務器可以同時發送和接收數據,而 HTTP 是單向的,客戶端發起請求,服務器響應數據。
          • 協議標識:WebSocket 使用 ws:// 或 wss:// 前綴標識,而 HTTP 使用 http:// 或 https://

          WebSocket 的優勢和適用場景是什么?

          WebSocket 相對于傳統的 HTTP 請求具有以下優勢:

          • 實時性:WebSocket 提供了低延遲的實時通信能力,能夠在服務器端有新數據時立即推送給客戶端。
          • 雙向通信:WebSocket 支持客戶端和服務器之間的雙向通信,可以實現實時聊天、實時數據更新等場景。
          • 較低的網絡開銷:WebSocket 使用長連接,相對于頻繁的短連接請求,減少了網絡開銷。
          • 更高的性能:由于減少了 HTTP 請求的開銷,WebSocket 在性能上更高效。
          • 跨域支持:WebSocket 具備跨域通信的能力,可以跨域進行實時通信。

          WebSocket 的適用場景包括實時聊天應用、股票行情推送、實時協作編輯、多人游戲、實時數據監控等需要實時雙向通信的場景。

          WebSocket 的連接建立過程是怎樣的?

          WebSocket 的連接建立過程包括以下步驟:

          1. 客戶端發送 WebSocket 握手請求,請求頭包含 Upgrade 和 Connection 字段,指定協議升級和建立連接。
          2. 服務器收到握手請求后,驗證請求頭的字段,并返回握手響應,響應頭包含 Upgrade 和 Connection 字段,以及一個隨機的 Sec-WebSocket-Key 字段。
          3. 客戶端收到握手響應后,驗證響應頭的字段,并生成一個 Sec-WebSocket-Accept 值進行驗證。
          4. 驗證通過后,WebSocket 連接建立成功,客戶端和服務器可以開始進行實時通信。

          WebSocket 的事件有哪些?請分別描述它們的作用。

          WebSocket 提供了以下幾種事件:

          • open:當 WebSocket 連接成功建立時觸發的事件。可以在此事件中執行初始化操作或向服務器發送初始數據。
          • message:當從服務器接收到新消息時觸發的事件。可以在此事件中處理接收到的數據。
          • error:當出現連接錯誤時觸發的事件。錯誤可能包括連接失敗、數據傳輸錯誤等。可以在此事件中處理錯誤并采取適當的措施。
          • close:當 WebSocket 連接關閉時觸發的事件。關閉可能是由服務器或客戶端發起的,可以在此事件中執行清理操作或重新連接等操作。

          這些事件可以通過設置對應的事件處理函數來處理不同的連接狀態和數據傳輸。

          在瀏覽器端如何創建和使用 WebSocket 對象?

          在瀏覽器端,可以使用 JavaScript 中的 WebSocket 對象來創建和使用 WebSocket。示例代碼如下:

          const socket=new WebSocket('wss://example.com/socket');
          


          其中,new WebSocket() 通過傳入服務器的 WebSocket URL 來創建一個 WebSocket 對象。然后可以通過設置事件處理函數來處理 WebSocket 的事件,例如:

          socket.onopen=function(event) {
            console.log('WebSocket 連接已打開');
          };
          
          socket.onmessage=function(event) {
            const message=event.data;
            console.log('接收到消息:', message);
          };
          
          socket.onerror=function(error) {
            console.error('WebSocket 錯誤:', error);
          };
          
          socket.onclose=function(event) {
            console.log('WebSocket 連接已關閉');
          };
          
          


          在連接建立成功后,可以使用 send() 方法發送消息到服務器,例如:

          socket.send('Hello, server!');
          


          如何發送和接收消息?有哪些方法可以發送二進制數據?

          通過 WebSocket 的 send() 方法可以向服務器發送消息,例如:

          socket.send('Hello, server!');
          


          接收到的消息可以在 onmessage 事件處理函數中進行處理,例如:

          socket.onmessage=function(event) {
            const message=event.data;
            console.log('接收到消息:', message);
          };
          
          


          WebSocket 除了發送和接收文本消息外,還支持發送和接收二進制數據。對于發送二進制數據,可以使用 send() 方法傳遞一個 ArrayBuffer 或 Blob 對象,例如:

          const buffer=new ArrayBuffer(4);
          const view=new DataView(buffer);
          view.setUint32(0, 1234);
          socket.send(buffer);
          
          


          在接收二進制數據時,可以通過 event.data 獲取到 ArrayBuffer 對象,然后進行處理。

          如何處理錯誤和關閉連接?

          WebSocket 在出現錯誤時會觸發 error 事件,可以通過設置 onerror 事件處理函數來處理錯誤,例如:

          socket.onerror=function(error) {
            console.error('WebSocket 錯誤:', error);
          };
          
          


          當 WebSocket 連接關閉時,會觸發 close 事件,可以通過設置 onclose 事件處理函數來執行一些清理操作或重新連接等操作,例如:

          socket.onclose=function(event) {
            console.log('WebSocket 連接已關閉');
          };
          
          


          可以通過調用 close() 方法來顯式地關閉 WebSocket 連接,例如:

          socket.close();
          
          


          WebSocket 的安全性和跨域問題如何處理?

          WebSocket 支持通過 wss:// 前綴建立加密的安全連接,使用 TLS/SSL 加密通信,確保數據的安全性。在使用加密連接時,服務器需要配置相應的證書。

          對于跨域問題,WebSocket 遵循同源策略,只能與同源的服務器建立連接。如果需要與不同域的服務器通信,可以使用 CORS(跨域資源共享)來進行跨域訪問控制。

          在實際應用中,如何處理連接狀態的變化和重連機制?

          在實際應用中,可以通過監聽 open、error 和 close 事件來處理連接狀態的變化。當連接關閉時,可以根據需要執行重連機制,例如使用指數退避算法進行重連,以確保連接的穩定性和可靠性。

          WebSocket 的性能如何優化?有哪些注意事項和最佳實踐?

          為了優化 WebSocket 的性能,可以考慮以下幾個方面:

          • 減少數據量:合理控制發送的數據量大小,避免不必要的數據傳輸。
          • 心跳機制:通過定時發送心跳消息,保持連接的活躍狀態,防止連接被關閉。
          • 數據壓縮:可以使用壓縮算法對數據進行壓縮,減少網絡傳輸的數據量。
          • 服務器端優化:合理配置服務器端的連接數和資源管理,以支持更多的并發連接。

          WebSocket 和長輪詢相比,各自有什么優缺點?

          WebSocket 和長輪詢都可以實現實時通信,但它們具有不同的特點和適用場景。

          WebSocket 的優點:

          • 實時性:WebSocket 建立一次連接后可以進行持久通信,實時性較高。
          • 雙向通信:WebSocket 支持客戶端和服務器之間的雙向通信。
          • 較低的網絡開銷:WebSocket 使用長連接,減少了網絡開銷。

          WebSocket 的缺點:

          • 兼容性:部分老舊的瀏覽器可能不支持 WebSocket,需要進行兼容處理。
          • 服務器支持:服務器需要支持 WebSocket 協議和相關處理邏輯。

          長輪詢的優點:

          • 兼容性:長輪詢可以在所有支持 HTTP 的瀏覽器中使用。
          • 簡單實現:相對于 WebSocket,長輪詢的實現較為簡單。

          長輪詢的缺點:

          • 延遲較高:由于需要不斷發起輪詢請求,延遲相對較高。
          • 頻繁的請求:長輪詢需要頻繁地發送請求,增加了服務器的負載。

          根據具體需求和場景,選擇合適的方案來實現實時通信。如果需要更高的實時性和較低的網絡開銷,WebSocket 是更好的選擇。如果兼容性要求較高或者對實時性要求不高,可以考慮使用長輪詢。


          作者:囂張農民
          鏈接:https://juejin.cn/post/7288963909591138344


          主站蜘蛛池模板: 国产吧一区在线视频| 亚洲日韩国产精品第一页一区| 国产成人久久精品区一区二区 | 无码av不卡一区二区三区| 国产精品男男视频一区二区三区| 国产激情视频一区二区三区| 午夜视频久久久久一区 | 日韩视频免费一区二区三区| 精品人妻少妇一区二区| 性色AV一区二区三区无码| 亚洲国产av一区二区三区丶| 韩国女主播一区二区| 精品一区高潮喷吹在线播放| 亚洲伦理一区二区| 国产在线无码视频一区| 国产福利一区二区三区视频在线| 曰韩人妻无码一区二区三区综合部 | 另类一区二区三区| 国产成人久久一区二区不卡三区| 加勒比精品久久一区二区三区| 色老板在线视频一区二区| 无码一区二区波多野结衣播放搜索| 精品亚洲A∨无码一区二区三区 | 精品一区二区三区高清免费观看| 亚洲欧美日韩一区二区三区在线 | 久久影院亚洲一区| 国产精品一区二区毛卡片| 精品动漫一区二区无遮挡| 免费看AV毛片一区二区三区| 日本一区二区三区精品国产 | 日本一区二区三区在线观看视频| 久久久久久人妻一区二区三区| 国产高清在线精品一区二区| 久久99国产精一区二区三区| 久久亚洲AV午夜福利精品一区| 亚洲精品无码一区二区| 一区免费在线观看| 亚洲欧洲专线一区| 精品天海翼一区二区| 日韩视频一区二区| 国产精品一区二区无线|