javascript EventSource:實(shí)時(shí)服務(wù)器端推送
當(dāng)涉及到向前端應(yīng)用程序提供實(shí)時(shí)數(shù)據(jù)時(shí),Web 開發(fā)人員需要一種可以無縫工作的解決方案。一般情況下,前端應(yīng)用程序會(huì)定期向服務(wù)器發(fā)送請求以獲取更新,但是這會(huì)浪費(fèi)寶貴的帶寬資源和服務(wù)器資源。在這種情況下,javascript EventSource 就成為了一種更為高效的解決方案。
#?背景
在使用 chatgpt 時(shí)。實(shí)時(shí)的獲取到 chatgpt 的回復(fù)。但是我發(fā)現(xiàn)在輸入 prompt 后,只有一個(gè)請求。但是他的消息是實(shí)時(shí)動(dòng)態(tài)顯示的,起初以為使用了 WebSocket,但經(jīng)過查看源碼發(fā)現(xiàn)并沒有使用 WebSocket。而是使用了 EventSource。
#?什么是 EventSource?
javascript EventSource 是一個(gè)內(nèi)置在現(xiàn)代瀏覽器中的 API,它允許服務(wù)器向客戶端發(fā)送實(shí)時(shí)事件。該 API 建立一個(gè)持久化的連接,通過該連接,服務(wù)器可以隨時(shí)向客戶端推送數(shù)據(jù)。該 API 建立的連接基于 HTTP 協(xié)議,而不是 WebSocket,因此不需要使用其他庫或框架,即可在應(yīng)用程序中使用它。
#?EventSource 的工作原理
EventSource 基于 HTTP 協(xié)議實(shí)現(xiàn),通過與服務(wù)器建立一個(gè)持續(xù)連接,實(shí)現(xiàn)了服務(wù)器向客戶端推送事件數(shù)據(jù)的功能。在客戶端,EventSource 對象通過一個(gè) URL 發(fā)起與服務(wù)器的連接。連接成功后,服務(wù)器可以向客戶端發(fā)送事件數(shù)據(jù)。在客戶端,通過 EventSource 對象注冊事件處理函數(shù),以接收來自服務(wù)器的事件數(shù)據(jù)。
以下是 EventSource 的工作原理:
客戶端向服務(wù)器發(fā)起 HTTP GET 請求,請求一個(gè)特定的 URL。
服務(wù)器接收請求,并在 HTTP 頭中添加 "Content-Type: text/event-stream"。
服務(wù)器建立一個(gè)持續(xù)的 HTTP 連接,向客戶端發(fā)送數(shù)據(jù),直到連接被關(guān)閉。
當(dāng)服務(wù)器有新的事件數(shù)據(jù)要發(fā)送時(shí),它將這些數(shù)據(jù)以特定的格式發(fā)送給客戶端。事件數(shù)據(jù)格式如下:
其中,event 字段表示事件名,data 字段表示事件數(shù)據(jù)。
客戶端通過 EventSource 對象注冊事件處理函數(shù),以接收來自服務(wù)器的事件數(shù)據(jù)。當(dāng)客戶端接收到來自服務(wù)器的事件數(shù)據(jù)時(shí),它將創(chuàng)建一個(gè) Event 對象,并觸發(fā)相應(yīng)的事件處理函數(shù),傳遞 Event 對象作為參數(shù)。Event 對象包含以下屬性:
當(dāng)連接出現(xiàn)錯(cuò)誤或被關(guān)閉時(shí),客戶端將觸發(fā) "error" 事件或 "close" 事件,以便進(jìn)行錯(cuò)誤處理或重新連接??偟膩碚f,EventSource 建立了一種持久化的 HTTP 連接,實(shí)現(xiàn)了服務(wù)器向客戶端實(shí)時(shí)推送事件數(shù)據(jù)的功能。它非常適合于需要實(shí)時(shí)更新的應(yīng)用程序,例如聊天室、股票市場等等。
#?如何使用 javascript EventSource?
使用 EventSource 非常簡單。在前端,我們只需要使用它提供的構(gòu)造函數(shù),指定從服務(wù)器接收事件的 URL 即可:
在這個(gè)例子中,我們將通過一個(gè)名為"my-endpoint”的 URL 從服務(wù)器獲取事件。服務(wù)器應(yīng)該根據(jù)需要設(shè)置此 URL 并在客戶端上公開它。
一旦建立連接,服務(wù)器就可以使用以下語法向客戶端發(fā)送事件:
這將向所有當(dāng)前連接到 EventSource 實(shí)例的客戶端發(fā)送一個(gè)名為"eventName”的事件,并附帶一個(gè)包含"eventData”的數(shù)據(jù)對象。
客戶端可以使用以下語法來監(jiān)聽事件:
這將為名為"eventName”的事件注冊一個(gè)偵聽器。每當(dāng)服務(wù)器發(fā)送此事件時(shí),客戶端都會(huì)接收到一個(gè)帶有事件數(shù)據(jù)的 Event 對象。在此例中,我們將其打印到控制臺(tái)中。
此外,EventSource 還提供了其他一些有用的功能,例如錯(cuò)誤處理和自定義事件重試。例如,我們可以使用以下語法來處理與 EventSource 相關(guān)的錯(cuò)誤:
這將為所有 EventSource 錯(cuò)誤注冊一個(gè)處理程序。每當(dāng)出現(xiàn)錯(cuò)誤時(shí),客戶端都會(huì)接收到一個(gè)帶有錯(cuò)誤信息的 Event 對象。在這個(gè)例子中,我們將其打印到控制臺(tái)中。
#?總結(jié)
總體來說,javascript EventSource 是一種非常有用的技術(shù),可以使前端應(yīng)用程序獲得實(shí)時(shí)數(shù)據(jù)而無需頻繁地從服務(wù)器獲取更新。由于其內(nèi)置于現(xiàn)代瀏覽器中,因此使用 EventSource 非常容易,而且不需要使用額外的庫或框架。
#?EventSource 與 WebSocket Http 的對比
EventSource 和 WebSocket 都是用于實(shí)現(xiàn)客戶端與服務(wù)器之間實(shí)時(shí)雙向通信的技術(shù),但它們在很多方面有著不同的特點(diǎn)和適用場景。
協(xié)議 EventSource 基于 HTTP 協(xié)議,使用的是 HTTP 的長連接機(jī)制,而 WebSocket 則是一種獨(dú)立的協(xié)議,與 HTTP 沒有關(guān)系。
雙向通信 WebSocket 支持雙向通信,客戶端和服務(wù)器都可以主動(dòng)發(fā)送數(shù)據(jù)。而 EventSource 只支持服務(wù)器向客戶端的單向通信,客戶端只能接收數(shù)據(jù),不能主動(dòng)發(fā)送數(shù)據(jù)。
數(shù)據(jù)格式 WebSocket 可以發(fā)送任意格式的數(shù)據(jù),包括文本、二進(jìn)制等。而 EventSource 僅支持純文本格式,采用了一種特殊的格式來傳輸事件數(shù)據(jù)。
瀏覽器兼容性 WebSocket 是 HTML5 新增的標(biāo)準(zhǔn),兼容性相對較差,在一些舊版本的瀏覽器中不支持。而 EventSource 的兼容性相對較好,在大多數(shù)現(xiàn)代瀏覽器中都能夠正常工作。
實(shí)時(shí)性 WebSocket 的實(shí)時(shí)性更高,它的通信速度和性能都比 EventSource 更優(yōu)秀。因?yàn)?WebSocket 是雙向通信,數(shù)據(jù)傳輸?shù)男矢?,?EventSource 由于是單向通信,數(shù)據(jù)傳輸?shù)乃俣葧?huì)稍慢一些。
總的來說,WebSocket 和 EventSource 都有著自己的優(yōu)點(diǎn)和適用場景。WebSocket 更適合需要雙向通信的應(yīng)用場景,例如實(shí)時(shí)游戲、在線協(xié)作等等。而 EventSource 則更適合需要單向數(shù)據(jù)推送的應(yīng)用場景,例如實(shí)時(shí)監(jiān)控、股票行情等等。因此,在選擇使用哪種技術(shù)時(shí),需要根據(jù)具體的需求進(jìn)行選擇。
#?實(shí)例
本文使用?文章同步助手?同步
?