使用 new EventSource 實現前端實時通信

示例:

eventSource單向通信

1. 什么是 EventSource?

EventSource 是瀏覽器提供的一種實現服務器推送(Server-Sent Events,簡稱 SSE)功能的 API。它是基于 HTTP 協議的單向通信機制,可以通過服務器將實時數據推送到客戶端,而不需要客戶端不斷發起請求。

與傳統的 AJAX 請求(如 XMLHttpRequest 或 fetch)不同,EventSource 會創建一個長連接,允許服務器主動向瀏覽器推送數據。這使得前端可以高效地接收實時數據,而不必通過輪詢來獲取更新。

為什么使用 EventSource?

  • 實時性強:可以在服務器有更新時即時推送數據,而不需要客戶端不斷請求。
  • 低延遲:相比于輪詢,EventSource 更加高效,因為它不會不斷地向服務器發起 HTTP 請求。
  • 簡潔的 API:EventSource 的用法非常簡潔,只需要一行代碼即可實現連接,并且可以輕松處理服務器推送的數據。

2. EventSource 的基本用法

EventSource 是通過 new EventSource(url) 創建的,參數 url 是服務器端提供的推送數據的接口。服務器會向客戶端推送實時數據,并以 text/event-stream 格式傳輸。

基本語法

const eventSource = new EventSource('your-server-endpoint');

監聽服務器發送的事件
EventSource 提供了幾個事件來監聽服務器端推送的消息:

  • message:默認事件,接收到消息時觸發。
  • open:連接成功時觸發。
  • error:連接出錯時觸發。

示例代碼
假設我們有一個服務器端接口 /events,該接口會定期向客戶端推送消息。

// 創建 EventSource 實例
const eventSource = new EventSource('/events');// 監聽連接成功事件
eventSource.addEventListener('open', function(event) {console.log('連接已成功建立');
});// 監聽消息事件
eventSource.addEventListener('message', function(event) {console.log('收到消息:', event.data);
});// 監聽連接出錯事件
eventSource.addEventListener('error', function(event) {if (event.eventPhase == EventSource.CLOSED) {console.log('連接已關閉');} else {console.log('發生錯誤:', event);}
});

代碼解析:

  • new EventSource(‘/events’):創建與服務器的連接,/events 是服務器端的推送接口。
  • eventSource.addEventListener(‘message’, callback):監聽 message 事件,callback 會在接收到推送消息時執行,event.data 包含服務器發送的消息內容。
  • eventSource.addEventListener(‘open’, callback):監聽連接成功事件,當連接成功時會調用此回調函數。
  • eventSource.addEventListener(‘error’, callback):監聽錯誤事件,如果連接失敗或被關閉,會觸發該事件。

3. 服務器端的實現

在服務器端,我們需要將數據按 text/event-stream 的格式發送給客戶端,通常使用一種流式的方式將數據傳輸給瀏覽器。以下是一個用 Node.js 和 Express 實現的簡單 SSE 服務器示例:

const express = require('express');
const app = express();app.get('/events', (req, res) => {res.setHeader('Content-Type', 'text/event-stream');res.setHeader('Cache-Control', 'no-cache');res.setHeader('Connection', 'keep-alive');let count = 0;setInterval(() => {count++;res.write(`data: 這是第 ${count} 條實時消息\n\n`);}, 1000);
});app.listen(3000, () => {console.log('服務器正在監聽端口 3000');
});

代碼解析:
res.setHeader(‘Content-Type’, ‘text/event-stream’):告訴瀏覽器返回的是一個事件流。
setInterval():每隔 1 秒推送一次消息,模擬服務器實時推送數據給客戶端。
啟動服務器并訪問
啟動服務器:node server.js
在瀏覽器中打開前端頁面,監聽來自 /events 接口的數據。

4. EventSource 的高級用法

自定義事件
在 SSE 中,客戶端可以根據需要使用自定義事件來處理不同類型的數據,而不僅僅是 message 事件。可以使用 event 屬性來定義自定義事件。

代碼示例:

// 服務器端
res.write('event: customEvent\n');
res.write('data: 這是一個自定義事件\n\n');// 客戶端
eventSource.addEventListener('customEvent', function(event) {console.log('收到自定義事件:', event.data);
});

自動重連
EventSource 會在連接斷開后自動重連,默認重連時間為 3 秒,可以通過設置 retry 屬性來指定自定義的重連時間。
代碼示例:

// 服務器端
res.write('retry: 5000\n');  // 重連時間為 5000 毫秒(5秒)

關閉連接
在前端代碼中,可以使用 eventSource.close() 來主動關閉連接。

eventSource.close();

5. EventSource 與其他通信技術的比較

與 WebSocket 的對比
EventSource 和 WebSocket 都可以實現服務器向客戶端的實時數據推送,但它們有不同的適用場景:

  • EventSource:是單向通信,適合用來從服務器向客戶端推送數據,比如實時通知、新聞更新等。
  • WebSocket:是雙向通信,適合需要客戶端和服務器之間進行雙向交互的場景,如在線聊天、實時協作等。

與輪詢的對比
輪詢是通過定時向服務器發送請求獲取最新的數據,缺點是每次都需要發起 HTTP 請求,帶來不必要的開銷。而 EventSource 是建立一個持久連接,服務器主動推送數據,避免了頻繁的 HTTP 請求。

6. 總結

EventSource 提供了一種簡單、有效的方式來實現服務器推送數據到前端。與傳統的輪詢相比,它能夠減少請求開銷,提高實時性。它也比 WebSocket 更容易實現和使用,適合單向數據流的應用場景。

優點:

  • 實現簡單。
  • 低延遲,適合實時通知等應用。
  • 自動重連功能,保證連接的穩定性。

缺點:

  • 只支持單向通信,不能用于需要雙向通信的場景(此時可以選擇 WebSocket)。
  • 瀏覽器支持較為有限,雖然現代瀏覽器普遍支持,但在一些老舊瀏覽器中可能無法使用。

通過使用 EventSource,開發者可以輕松地在 Web 應用中實現實時數據流功能,為用戶提供更好的交互體驗。

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

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

相關文章

Android Input——查找并添加目標窗口(七)

在 Android 輸入系統中,InputDispatcher 的核心職責之一是將輸入事件正確地傳遞到目標窗口。上一篇文章我們介紹到 InputDispatcher 事件分發調用到 findFocusedWindowTargetsLocked() 函數查找焦點窗口,并將焦點窗口添加到目標窗口,這里我們繼續往下看。 一、獲取焦點窗口…

Spring Boot中Spring MVC相關配置的詳細描述及表格總結

以下是Spring Boot中Spring MVC相關配置的詳細描述及表格總結: Spring MVC 配置項詳解 1. 異步請求配置 spring.mvc.async.request-timeout 描述:設置異步請求的超時時間(單位:毫秒)。默認值:未設置&…

HTTP GET 和 POST 請求有什么區別

HTTP 的 GET 和 POST 請求是兩種常見的 HTTP 請求方法,它們有不同的特點和應用場景。以下是它們的主要區別: 1. 用途 GET:用于從服務器獲取數據或資源。GET 請求會附帶查詢參數在 URL 中,通常用于請求數據,如加載網頁…

從入門到精通【MySQL】 聯合查詢

文章目錄 📕摘要📕1. 多表聯合查詢時MySQL內部原理??1.1 實例:一個完整的聯合查詢過程 📕2. 內連接📕3. 外連接📕4. 自連接📕5. 子查詢??5.1 單行子查詢??5.2 多行子查詢??5.3 多列子查…

高可用之戰:Redis Sentinal(哨兵模式)

參考:Redis系列24:Redis使用規范 - Hello-Brand - 博客園 1 背景 在我們的《Redis高可用之戰:主從架構》篇章中,介紹了Redis的主從架構模式,可以有效的提升Redis服務的可用性,減少甚至避免Redis服務發生完…

加密≠安全:文件夾密碼遺忘背后的數據丟失風險與應對

在數字化時代,保護個人隱私和數據安全變得尤為重要。許多人選擇對重要文件夾進行加密,以防止未經授權的訪問。然而,一個常見且令人頭疼的問題也隨之而來——文件夾加密密碼遺忘。當你突然發現自己無法訪問那些加密的文件夾時,那種…

WPS宏開發手冊——附錄

目錄 系列文章7、附錄 系列文章 使用、工程、模塊介紹 JSA語法 JSA語法練習題 Excel常用Api Excel實戰 常見問題 附錄 7、附錄 顏色序列:在excel中設置顏色,只能設置顏色序號,不能直接設置rgb顏色 1、黑色 (Black)…

C++基礎精講-02

文章目錄 1.C/C申請、釋放堆空間的方式對比1.1C語言申請、釋放堆空間1.2C申請、釋放堆空間1.2.1 new表達式申請數組空間 1.3回收空間時的注意事項1.4malloc/free 和 new/delete 的區別 2.引用2.1 引用的概念2.2 引用的本質2.3 引用與指針的聯系與區別2.4 引用的使用場景2.4.1 引…

Spring Boot MongoDB 分頁工具類封裝 (新手指南)

Spring Boot MongoDB 分頁工具類封裝 (新手指南) 目錄 引言&#xff1a;為何需要分頁工具類&#xff1f;工具類一&#xff1a;PaginationUtils - 簡化 Pageable 創建 設計目標代碼實現 (PaginationUtils.java)如何使用 PaginationUtils 工具類二&#xff1a;PageResponse<…

MyBatis的緩存、逆向工程、使用PageHelper、使用PageHelper

一、MyBatis的緩存 緩存&#xff1a;cache 緩存的作用&#xff1a;通過減少IO的方式&#xff0c;來提高程序的執行效率。 mybatis的緩存&#xff1a;將select語句的查詢結果放到緩存&#xff08;內存&#xff09;當中&#xff0c;下一次還是這條select語句的話&#xff0c;直…

java中的JNI調用c庫

1. 簡單demo 如果是在某個項目中有包名就需要自己找ai問問去改寫下cmd命令去編譯執行等 java文件&#xff08;HelloJNI.java&#xff09; public class HelloJNI {// 聲明 native 方法public native void sayHello();// 加載本地庫static {System.loadLibrary("hello&quo…

人工智能:GPT技術應用與未來展望

GPT(Generative Pre-trained Transformer)作為自然語言處理領域的代表性技術,近年來在各行業的實際應用中展現出廣泛潛力。結合其技術特性與行業需求,以下是GPT的主要應用場景、案例分析及未來挑戰的總結: 一、核心應用領域與案例 文本生成與內容創作 自動化內容生產:GPT…

前端筆記-ECMAScript語法概覽

更多詳細可以查看1.1 ES6 教程 | 菜鳥教程 這里我將大概記錄ES與JS大概不一樣的部分&#xff0c;方便聯合記憶。 歷史與關系 ECMAScript&#xff1a;是一種由 Ecma 國際組織制定的腳本語言規范&#xff0c;它是 JavaScript 的標準化版本。ECMAScript 為 JavaScript 提供了語…

操作主機的管理

1.在AD林范圍內&#xff0c;有哪幾個操作主機角色 架構主機&#xff08;Schema Master&#xff09; 功能&#xff1a;負責整個AD林中所有對象和屬性的定義&#xff0c;是唯一可以更新目錄架構的DC。架構更新會從架構主機復制到目錄林中的所有其他域控制器。 作用范圍&#xf…

【Linux】網絡編程

目錄 端口號 網絡字節序 socket編程 接口 sockaddr結構 udp網絡程序 創建套接字 綁定 接收 發送 客戶端需要綁定嗎&#xff1f; 客戶端執行方法 本地環回地址 終端文件 代碼 tcp網絡程序 SOCK_STREAM 監聽 查詢網絡信息 獲取新連接 地址轉換函數 客戶端綁…

Go 語言中的select是做什么的

Go 語言中的 select 是做什么的 在 Go 語言中&#xff0c;select 語句是用于處理多個通道&#xff08;channel&#xff09;操作的一種控制結構。它類似于 switch 語句&#xff0c;但專門用于并發編程&#xff0c;允許 Goroutine 在多個通道上等待操作&#xff08;發送或接收&a…

智慧班牌系統解決方案,SaaS智慧電子班牌云平臺

智慧班牌系統解決方案 系統概述 智慧班牌是智慧校園建設不斷發展的產物&#xff0c;是教育信息化改革的載體。通過智慧班牌可以高效便捷傳遞各種知識信息和通知信息、及時反饋課堂信息、實現班級的透明化管理。智慧班牌將學生平安考勤、異常出勤情況及時反饋至家長、老師&…

利用大模型和聚類算法找出 Excel 文件中重復或相似度高的數據,并使用 FastAPI 進行封裝的詳細方案

以下是一個利用大模型和聚類算法找出 Excel 文件中重復或相似度高的數據,并使用 FastAPI 進行封裝的詳細方案: 方案流程 數據讀取:從 Excel 文件中讀取數據。文本向量化:使用大模型將文本數據轉換為向量表示。聚類分析:運用聚類算法對向量進行分組,將相似度高的數據歸為…

【Docker基礎】容器技術詳解:生命周期、命令與實戰案例

文章目錄 一、什么是容器&#xff1f;二、為什么需要容器三、容器的生命周期容器狀態容器OOM容器異常退出容器異常退出容器暫停 四、容器命令命令清單詳細介紹 五、容器操作案例容器的狀態遷移容器批量操作容器交互模式attached 模式detached 模式interactive 模式 容器 與 宿主…

Laravel 實現 隊列 發送郵件功能

一. 什么是隊列 在構建 Web 應用程序時&#xff0c;你可能需要執行一些任務&#xff0c;例如解析文件&#xff0c;發送郵件&#xff0c;大量的數據計算等等&#xff0c;這些任務在典型的 Web 請求期間需要很長時間才能執行。 慶幸的是&#xff0c;Laravel 可以創建在后臺運行…