Web 實時通信技術:WebSocket 與 Server-Sent Events (SSE) 深入解析

一、WebSocket:

(一)WebSocket 是什么?

WebSocket 是一種網絡通信協議,它提供了一種在單個 TCP 連接上進行全雙工通信的方式。與傳統的 HTTP 請求 - 響應模型不同,WebSocket 允許服務器和客戶端在連接建立后隨時互相發送數據,而無需重新建立連接。這種特性使得它在實時交互場景中具有得天獨厚的優勢。

(二)WebSocket 的工作原理

  1. 連接建立:WebSocket 的連接過程始于一個 HTTP 請求。客戶端通過在 HTTP 請求中添加特定的 Upgrade 和 Connection 頭,向服務器發起 WebSocket 升級請求。服務器如果支持 WebSocket,會返回一個 101 Switching Protocols 響應,表示連接已升級為 WebSocket。值得注意的是,在實際應用中,一些代理服務器或防火墻可能會對 WebSocket 的連接請求進行攔截,開發者需要進行相應的配置以確保連接順利建立。
  1. 數據傳輸:一旦連接建立,客戶端和服務器就可以通過幀的形式互相發送數據。WebSocket 支持多種數據類型,包括文本、二進制數據等。為了提高數據傳輸效率,在傳輸大量數據時,可以對數據進行壓縮處理,例如使用 Gzip 壓縮算法,減少網絡傳輸的數據量。
  1. 連接關閉:WebSocket 連接可以通過發送關閉幀來終止。關閉幀中可以包含關閉原因和狀態碼,便于調試和錯誤處理。在實際開發中,還需要考慮異常情況下的連接關閉處理,比如網絡中斷導致的連接意外關閉,此時需要及時進行重連操作以保證通信的連續性。

(三)WebSocket 的應用場景

  • 實時聊天應用:WebSocket 是聊天應用的理想選擇。它允許服務器在收到消息后立即推送給其他用戶,無需客戶端輪詢服務器。以 Slack 為例,它基于 WebSocket 實現了高效的實時聊天功能,用戶在發送消息后幾乎能瞬間看到對方的回復,極大地提升了溝通效率。
  • 在線游戲:游戲需要低延遲的通信來實時更新游戲狀態。WebSocket 的全雙工特性能夠滿足這一需求。像《Among Us》這樣的在線游戲,通過 WebSocket 實現了玩家之間實時的信息交互,包括角色位置、動作、對話等,保證了游戲的流暢性和趣味性。
  • 實時數據可視化:例如股票行情、體育賽事比分等,WebSocket 可以實時推送數據到客戶端進行展示。在金融領域,許多在線交易平臺利用 WebSocket 實時更新股票價格、交易數據等信息,幫助投資者及時做出決策。

(四)WebSocket 的優缺點

優點

  • 低延遲:一旦連接建立,數據傳輸無需重新建立連接,大大減少了通信延遲。在一些對實時性要求極高的場景,如在線直播彈幕互動,低延遲的 WebSocket 能夠讓用戶幾乎實時看到其他觀眾發送的彈幕。
  • 雙向通信:服務器和客戶端可以隨時互相發送數據,非常適合需要實時交互的場景。在在線教育平臺中,教師和學生可以通過 WebSocket 進行實時的問答互動,提高教學效果。
  • 支持多種數據類型:可以傳輸文本、二進制數據等,靈活性高。例如在傳輸圖片、音頻等多媒體數據時,WebSocket 能夠很好地勝任。

缺點

  • 復雜性較高:WebSocket 的實現相對復雜,需要處理連接管理、錯誤處理、重連機制等問題。在大型項目中,還需要考慮多用戶連接的并發處理,以避免服務器性能瓶頸。
  • 兼容性問題:雖然現代瀏覽器普遍支持 WebSocket,但在一些老舊的瀏覽器或網絡環境中可能會出現問題。為了解決兼容性問題,可以使用一些兼容性庫,如 socket.io,它在底層對 WebSocket 進行了封裝,并提供了額外的功能和更好的兼容性支持。

(五)WebSocket 的前端實現

在前端開發中,可以使用原生的 WebSocket API 來實現 WebSocket 通信。以下是一個簡單的示例代碼:


const socket = new WebSocket("wss://example.com/socket");socket.onopen = function (event) {console.log("WebSocket 已連接:", event);socket.send("客戶端已連接");};socket.onmessage = function (event) {console.log("從服務器收到消息:", event.data);};socket.onerror = function (error) {console.log("WebSocket 發生錯誤:", error);};socket.onclose = function (event) {console.log("WebSocket 已關閉:", event);};

在實際項目中,為了更好地管理 WebSocket 連接,可以將其封裝成一個單獨的模塊。例如:


class WebSocketService {constructor(url) {this.socket = new WebSocket(url);this.callbacks = {};this.socket.onopen = this.handleOpen.bind(this);this.socket.onmessage = this.handleMessage.bind(this);this.socket.onerror = this.handleError.bind(this);this.socket.onclose = this.handleClose.bind(this);}handleOpen(event) {console.log("WebSocket 已連接:", event);}handleMessage(event) {const data = JSON.parse(event.data);const callback = this.callbacks[data.type];if (callback) {callback(data);}}handleError(error) {console.log("WebSocket 發生錯誤:", error);}handleClose(event) {console.log("WebSocket 已關閉:", event);}sendMessage(message) {this.socket.send(JSON.stringify(message));}registerCallback(type, callback) {this.callbacks[type] = callback;}}// 使用示例const socketService = new WebSocketService("wss://example.com/socket");socketService.registerCallback("newMessage", (data) => {console.log("收到新消息:", data);});socketService.sendMessage({ type: "joinRoom", roomId: "123" });

二、Server-Sent Events (SSE):

(一)SSE 是什么?

Server-Sent Events (SSE) 是一種允許服務器向客戶端推送實時數據的技術。與 WebSocket 不同,SSE 是單向的,只能由服務器向客戶端發送數據,客戶端無法主動向服務器發送數據。這種特性使得 SSE 在一些只需要服務器推送數據的場景中表現出色。

(二)SSE 的工作原理

  1. 建立連接:客戶端通過在 HTML 中使用 <script> 標簽或在 JavaScript 中使用 EventSource API 向服務器發起請求。服務器響應時,需要設置 Content-Type 為 text/event-stream,表示這是一個 SSE 連接。在實際開發中,服務器端需要配置合適的響應頭,以確保 SSE 連接能夠正常建立。
  1. 數據推送:服務器通過特定的格式向客戶端發送數據。每次發送的數據以 data: 開頭,以兩個換行符結束。如果需要發送多個數據,可以連續發送多個這樣的格式。例如:

data: {"message": "第一條消息"}data: {"message": "第二條消息"}
  1. 連接保持:SSE 連接會一直保持打開狀態,直到客戶端關閉或服務器主動斷開。為了確保連接的穩定性,服務器可以定期發送一些心跳數據,防止連接被中間設備(如代理服務器)關閉。

(三)SSE 的應用場景

  • 新聞推送:例如新聞網站可以實時向用戶推送最新的新聞標題。像 BBC 新聞網站就使用了 SSE 技術,當有新的新聞發布時,能夠及時將新聞標題推送給用戶,用戶無需刷新頁面即可獲取最新信息。
  • 股票行情更新:服務器可以實時推送股票價格變化。在股票交易平臺中,SSE 能夠將股票的實時價格、漲跌幅等信息及時推送給投資者,方便投資者做出決策。
  • 日志流:服務器可以將日志信息實時推送給客戶端進行展示。在一些運維監控系統中,通過 SSE 將服務器的日志信息實時推送給運維人員,便于及時發現和處理問題。

(四)SSE 的優缺點

優點

  • 簡單易用:SSE 的實現相對簡單,前端只需要使用 EventSource API,后端也較為容易實現。對于一些小型項目或對實時數據推送需求不太復雜的場景,SSE 是一個快速實現的選擇。
  • 自動重連:瀏覽器會自動處理連接斷開后的重連邏輯,開發者無需手動實現。這大大減輕了開發者的負擔,提高了開發效率。
  • 兼容性較好:SSE 在現代瀏覽器中得到了較好的支持。與 WebSocket 相比,SSE 在兼容性方面表現更優,尤其是在一些對新技術支持不太友好的環境中。

缺點

  • 單向通信:只能由服務器向客戶端發送數據,無法實現雙向通信。這限制了 SSE 的應用場景,對于需要客戶端和服務器雙向交互的功能,SSE 無法滿足需求。
  • 連接數量限制:由于 SSE 是基于 HTTP 的,服務器可能會受到連接數量的限制。在高并發場景下,過多的 SSE 連接可能會導致服務器性能下降,甚至出現連接超時等問題。

(五)SSE 的前端實現

以下是一個使用 EventSource API 的示例代碼:


const eventSource = new EventSource("https://example.com/events");eventSource.onmessage = function (event) {console.log("從服務器收到消息:", event.data);};eventSource.onerror = function (error) {console.log("SSE 發生錯誤:", error);};eventSource.onopen = function (event) {console.log("SSE 已連接:", event);};

在實際應用中,有時需要處理自定義事件。SSE 支持自定義事件,只需要在服務器發送的數據中指定事件類型即可。例如:

服務器端發送數據:


event: customEventdata: {"message": "這是一個自定義事件消息"}

前端接收自定義事件:


const eventSource = new EventSource("https://example.com/events");eventSource.addEventListener('customEvent', function (event) {const data = JSON.parse(event.data);console.log("收到自定義事件消息:", data.message);});eventSource.onerror = function (error) {console.log("SSE 發生錯誤:", error);};eventSource.onopen = function (event) {console.log("SSE 已連接:", event);};

三、WebSocket 與 SSE 的對比

特性

WebSocket

Server-Sent Events (SSE)

通信方向

雙向通信(客戶端和服務器均可發送)

單向通信(僅服務器向客戶端發送)

實現復雜度

較高(需要處理連接管理、錯誤處理等)

較低(前端使用 EventSource,后端簡單)

兼容性

現代瀏覽器支持,但老舊瀏覽器可能不支持

現代瀏覽器支持較好

數據格式

支持文本和二進制數據

主要支持文本數據

自動重連

需要手動實現

瀏覽器自動處理

應用場景

實時聊天、在線游戲、實時數據可視化

新聞推送、股票行情、日志流

性能表現

在雙向通信場景下性能更優,可處理復雜交互

在單向推送場景下性能良好,資源消耗較低

安全性

需開發者手動處理安全問題,如身份驗證、數據加密

基于 HTTP,繼承 HTTP 的安全特性,相對簡單

四、選擇合適的實時通信技術

選擇 WebSocket 還是 SSE 取決于具體的應用場景和需求:

  • 如果需要雙向通信(例如聊天應用或在線游戲),WebSocket 是更好的選擇。同時,如果對數據傳輸的實時性和交互性要求較高,且能夠接受相對復雜的開發和維護工作,WebSocket 更為合適。
  • 如果只需要服務器向客戶端推送數據(例如新聞推送或股票行情),SSE 是一個更簡單且高效的解決方案。此外,當項目對兼容性要求較高,且希望快速實現單向數據推送功能時,SSE 是首選。

在一些復雜的項目中,也可以考慮將 WebSocket 和 SSE 結合使用。例如,在一個實時監控系統中,對于需要雙向交互的控制操作(如遠程控制設備)使用 WebSocket,而對于實時數據的展示(如設備狀態信息)使用 SSE,充分發揮兩者的優勢。

五、性能優化與安全防護

(一)性能優化

  1. WebSocket
  • 連接池:在服務器端建立連接池,復用已有的 WebSocket 連接,減少連接建立的開銷。當有新的客戶端請求連接時,優先從連接池中獲取可用連接,提高連接效率。
  • 心跳機制:設置合適的心跳間隔,定期發送心跳數據,保持連接的活性,防止連接因長時間閑置而被關閉。同時,通過心跳機制可以及時檢測到網絡異常,進行相應的重連操作。
  • 數據壓縮:如前文所述,對傳輸的數據進行壓縮處理,減少網絡傳輸的數據量,提高傳輸速度。可以使用 Gzip、Deflate 等壓縮算法。
  1. SSE
  • 批量推送:在服務器端將多個數據合并成一個消息進行推送,減少推送次數,降低服務器和網絡的壓力。例如,將多條新聞標題合并成一個消息推送給客戶端。
  • 緩存策略:合理設置緩存,對于一些不經常變化的數據,可以在客戶端進行緩存,減少不必要的數據傳輸。當數據發生變化時,服務器再推送更新后的消息。

(二)安全防護

  1. WebSocket
  • 身份驗證:在建立連接時,對客戶端進行身份驗證,確保只有合法的客戶端能夠連接到服務器。可以使用 JWT(JSON Web Token)等技術進行身份驗證。
  • 數據加密:對傳輸的數據進行加密,防止數據被竊取或篡改。可以使用 TLS/SSL 加密協議,保證數據在傳輸過程中的安全性。
  • 防止跨站 WebSocket 劫持(CSWSH):采用類似防止 CSRF(跨站請求偽造)的方法,在請求中添加有效的令牌,驗證請求的合法性。
  1. SSE
  • 同源策略:利用瀏覽器的同源策略,確保 SSE 連接只能從合法的源發起,防止惡意網站偽造 SSE 連接。
  • 數據過濾:在服務器端對發送的數據進行過濾和驗證,防止惡意數據被推送到客戶端。例如,對用戶輸入的數據進行合法性檢查,防止 XSS(跨站腳本攻擊)等安全問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79893.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79893.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79893.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL(8)什么是主鍵和外鍵?

主鍵&#xff08;Primary Key&#xff09;和外鍵&#xff08;Foreign Key&#xff09;是關系數據庫中用于定義和維護表之間關系的重要概念。以下是詳細的解釋、示例代碼和操作步驟。 主鍵&#xff08;Primary Key&#xff09; 定義 主鍵是表中的一個或多個字段&#xff0c;其…

任意復雜度的 JSON 數據轉換為多個結構化的 Pandas DataFrame 表格

以下是一個 完整、結構清晰、可運行的 Python 工具&#xff0c;用于將任意復雜度的 JSON 數據轉換為多個結構化的 Pandas DataFrame 表格。該工具支持嵌套對象、嵌套數組&#xff0c;并通過主鍵和外鍵建立表之間的關聯關系。 if __name__ "__main__":# 示例 JSON 數…

【SSL部署與優化?】??HTTP/2與HTTPS的協同效應

HTTP/2與HTTPS的協同效應&#xff1a;為何HTTP/2強制要求TLS 1.2&#xff1f; HTTP/2是HTTP協議的現代升級版&#xff0c;旨在通過多路復用、頭部壓縮等技術提升性能。然而&#xff0c;HTTP/2的設計與部署與HTTPS&#xff08;TLS加密&#xff09;緊密相關&#xff0c;甚至強制…

爬蟲請求頻率應控制在多少合適?

爬蟲請求頻率的控制是一個非常重要的問題&#xff0c;它不僅關系到爬蟲的效率&#xff0c;還涉及到對目標網站服務器的影響以及避免被封禁的風險。合理的請求頻率需要根據多個因素來綜合考慮&#xff0c;以下是一些具體的指導原則和建議&#xff1a; 一、目標網站的政策 查看網…

使用Visual Studio將C#程序發布為.exe文件

說明 .exe 是可執行文件&#xff08;Executable File&#xff09;的擴展名。這類文件包含計算機可以直接運行的機器代碼指令&#xff0c;通常由編程語言&#xff08;如 C、C、C#、Python 等&#xff09;編譯或打包生成。可以用于執行自動化操作&#xff08;執行腳本或批處理操…

分布式1(cap base理論 鎖 事務 冪等性 rpc)

目錄 分布式系統介紹 一、定義與概念 二、分布式系統的特點 三、分布式系統面臨的挑戰 四、分布式系統的常見應用場景 CAP 定理 BASE 理論 BASE理論是如何保證最終一致性的 分布式鎖的常見使用場景有哪些&#xff1f; 1. 防止多節點重復操作 2. 資源互斥訪問 3. 分…

常見相機焦段的分類及其應用

相機焦段是指鏡頭的焦距范圍&#xff0c;決定了拍攝時的視角、畫面范圍和透視效果。不同焦段適合不同的拍攝場景和主題&#xff0c;以下是常見焦段的分類及其應用&#xff1a; 一、焦段的核心概念 焦距&#xff1a;鏡頭光學中心到成像傳感器的距離&#xff08;單位&#xff1a…

H5S 視頻監控AWS S3 對象存儲

本文介紹一下如何使用S3對象存儲作為H5S 存儲空間進行錄像存儲 然后創建一個對象存儲&#xff0c;本文以minio 為例(實際項目親測天翼云)&#xff1a; 首先安裝 s3fs 如果是redhat系列&#xff0c;使用如下命令 sudo yum install epel-release sudo yum install s3fs-fuse …

算法第十八天|530. 二叉搜索樹的最小絕對差、501.二叉搜索樹中的眾數、236. 二叉樹的最近公共祖先

530. 二叉搜索樹的最小絕對差 題目 思路與解法 第一想法&#xff1a; 一個二叉搜索樹的最小絕對差&#xff0c;從根結點看&#xff0c;它的結點與它的最小差值一定出現在 左子樹的最右結點&#xff08;左子樹最大值&#xff09;和右子樹的最左結點&#xff08;右子樹的最小值…

Nginx 動靜分離在 ZKmall 開源商城靜態資源管理中的深度優化

在 B2C 電商高并發場景下&#xff0c;靜態資源&#xff08;圖片、CSS、JavaScript 等&#xff09;的高效管理直接影響頁面加載速度與用戶體驗。ZKmall開源商城通過對 Nginx 動靜分離技術的深度優化&#xff0c;將靜態資源響應速度提升 65%&#xff0c;帶寬成本降低 40%&#xf…

PostgREST:無需后端 快速構建RESTful API服務

在現代 Web 開發中&#xff0c;API 已成為連接前后端的核心橋梁&#xff0c;傳統的做法是通過后端框架來構建API接口&#xff0c;然后由前后端人員進行聯調。 PostgREST是基于無服務器的一種實現方案&#xff0c;允許開發者將PostgreSQL數據庫直接暴露為RESTful API&#xff0…

MySQL——九、鎖

分類 全局鎖表級鎖行級鎖 全局鎖 做全庫的邏輯備份 flush tables with read lock; unlock tables;在InnoDB引擎中&#xff0c;我們可以在備份時加上參數–single-transaction參數來完成不加鎖的一致性數據備份 mysqldump --single-transaction -uroot -p123456 itcast>…

基于 Kubernetes 部署容器平臺kubesphere

一 前言&#xff1a; k8s 大家都已經非常熟悉了&#xff0c;網上流傳著非常多的搭建部署文檔&#xff0c;有kubeadmin的有二進制的&#xff0c;還有基于第三方的部署工具的&#xff0c;反正是各種部署方法都有&#xff0c;k8s部署技術熱門可見一斑。但是不管哪種部署都需要了解…

RDD算子-行為算子

RDD 算子探秘&#xff1a;行為算子的深度解析與實戰應用? 在 Spark 的 RDD 編程模型中&#xff0c;轉換算子負責構建數據處理的邏輯流程&#xff0c;但真正觸發計算并產生最終結果的是行為算子&#xff08;Action Operators&#xff09;。與轉換算子的惰性求值特性不同&#…

Oracle — PL-SQL

介紹 Oracle PL/SQL是專為Oracle數據庫設計的過程化編程語言&#xff0c;深度融合SQL語句與結構化編程邏輯&#xff0c;旨在高效處理復雜數據操作與業務規則。其核心特征為“塊結構”&#xff0c;程序由聲明、執行、異常處理三部分組成&#xff0c;支持模塊化開發&#xff0c;顯…

高防ip支持哪些網絡協議

高防IP通常支持多種網絡協議&#xff0c;以提供全面的網絡安全防護。以下是一些主要支持的網絡協議及其相關說明&#xff1a; TCP協議&#xff08;傳輸控制協議&#xff09;&#xff1a; TCP協議是最常見的傳輸協議&#xff0c;廣泛應用于互聯網通信。高防IP通過對TCP協議的防…

Flutter基礎()

導航欄 appBar: AppBar() title: const Text(搜索) //標題 backgroundColor: Colors.blue //背景顏色 centerTitle: true //標題居中leading 屬性 作用&#xff1a; 放置在應用欄左側的控件&#xff0c;通常是一個圖標按鈕&#xff0c;用于導航或打開菜單。 AppBar(le…

ESP系列單片機選擇指南:結合實際場景的最優選擇方案

前言 在物聯網(IoT)快速發展的今天&#xff0c;ESP系列單片機憑借其優異的無線連接能力和豐富的功能特性&#xff0c;已成為智能家居、智慧農業、工業自動化等領域的首選方案。本文將深入分析各款ESP芯片的特點&#xff0c;結合典型應用場景&#xff0c;幫助開發者做出最優選擇…

搭建Caffeine+Redis多級緩存機制

本地緩存的簡單實現方案有HashMap&#xff0c;CucurrentHashMap&#xff0c;成熟的本地緩存方案有Guava 與 Caffeine &#xff0c;企業級應用推薦下面說下兩者的區別 1. 核心異同對比 特性Guava CacheCaffeine誕生背景Google Guava 庫的一部分&#xff08;2011年&#xff09;…

【Linux系統】第四節—詳解yum+vim

hello 我是云邊有個稻草人 Linux—本節課所屬專欄—歡迎訂閱—持續更新中~ 目錄 畫板—本節課知識點詳解 一、軟件包管理器 1.1 什么是軟件包 1.2 Linux軟件?態 1.3 yum具體操作 【查看軟件包】 【安裝軟件】 【卸載軟件】 【注意事項】 1.4 安裝源 二、vim 2.1 …