簡介
不知道大家有沒有見過 Content-Type:text/event-stream
的請求頭,這是 HTML5
中的 EventSource
是一項強大的 API
,通過服務(wù)器推送實現(xiàn)實時通信。
與 WebSocket
相比,EventSource
提供了一種簡單而可靠的單向通信機制(服務(wù)器->客戶端),實現(xiàn)簡單,適用于許多實時應(yīng)用場景。
本文將介紹 EventSource
的簡單使用、與 WebSocket
的對比以及其優(yōu)缺點,最后對其進行總結(jié)。
EventSource
客戶端從服務(wù)端訂閱一條“流”,之后服務(wù)端可以發(fā)送消息給客戶端直到服務(wù)端或者客戶端關(guān)閉該“流”,所以 EventSource
也叫作 SSE(server-sent-event)
。
-
EventSource
是HTML5
中的一項API
,用于在客戶端和服務(wù)器之間建立持久的、單向的通信連接。 - 它基于
HTTP
協(xié)議,通過服務(wù)器推送的方式向客戶端發(fā)送實時事件通知。 - 客戶端通過添加事件偵聽器來捕獲事件并執(zhí)行相應(yīng)的操作。
簡單使用
示例:
服務(wù)器端使用 Go
創(chuàng)建了一個路由 /events
,當(dāng)客戶端通過 EventSource
對象連接到該路由時,服務(wù)器會不斷地發(fā)送事件流(每隔2秒發(fā)送一個事件)。客戶端的 HTML
頁面中使用 JavaScript
創(chuàng)建了一個 EventSource
對象,通過 onmessage
事件,將接收到的事件數(shù)據(jù)添加到頁面中。如果發(fā)生錯誤,客戶端會關(guān)閉 EventSource
連接。
文件結(jié)構(gòu)如下
程序目錄
- main.go
- c1.html
go 服務(wù)
package main
import (
"fmt"
"gopkg.in/antage/eventsource.v1"
"log"
"net/http"
"time"
)
func main() {
es := eventsource.New(nil, nil)
defer es.Close()
http.Handle("/", http.FileServer(http.Dir("./")))
http.Handle("/events", es)
go func() {
for {
// 每2秒發(fā)送一條當(dāng)前時間消息,并打印對應(yīng)客戶端數(shù)量
es.SendEventMessage(fmt.Sprintf("hello, now is: %s", time.Now()), "", "")
log.Printf("Hello has been sent (consumers: %d)", es.ConsumersCount())
time.Sleep(2 * time.Second)
}
}()
log.Println("Open URL http://localhost:8080/ in your browser.")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal(err)
}
}
前端 HTML
<!DOCTYPE html>
<html>
<head>
<title>SSE test</title>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded", function () {
var evsrc = new EventSource("http://localhost:8080/events");
var msgEvent = function (ev) {
document.getElementById("log")
.insertAdjacentHTML("beforeend", "<li>" + ev.data + "</li>");
}
evsrc.onmessage = msgEvent;
//evsrc.addEventListener("message", msgEvent)
evsrc.onerror = function (ev) {
console.log("readyState = " + ev.currentTarget.readyState);
}
})
</script>
</head>
<body>
<h1>SSE test</h1>
<div>
<ul id="log">
</ul>
</div>
</body>
</html>
服務(wù)啟動后訪問 http://localhost:8080/c1.html 可見如下頁面
和 websocket 的對比
EventSource 的優(yōu)點
- 簡單易用:
EventSource
使用簡單,基于標(biāo)準(zhǔn)的HTTP
協(xié)議,無需復(fù)雜的握手過程。 - 自動重連:
EventSource
具有內(nèi)置的重連機制,確保連接中斷后自動重新連接。 - 輕量級:
EventSource
使用長輪詢機制,消耗的資源相對較少,適合低帶寬環(huán)境。 - 跨域支持:
EventSource
允許在跨域環(huán)境下進行通信,通過適當(dāng)?shù)捻憫?yīng)頭授權(quán)來自不同域的客戶端連接。
EventSource 的缺點
- 單向通信:
EventSource
只支持服務(wù)器向客戶端的單向通信,無法實現(xiàn)客戶端向服務(wù)器的實時交互。 - 較低的瀏覽器支持:盡管現(xiàn)代瀏覽器廣泛支持
EventSource
,但在一些較舊的瀏覽器中可能不完全支持。
WebSocket 的優(yōu)點
- 雙向通信:
WebSocket
支持全雙工通信,客戶端和服務(wù)器可以在同一連接上進行雙向數(shù)據(jù)交換。 - 實時性和效率:
WebSocket
具有低延遲和高效性能,適用于需要快速、實時響應(yīng)的應(yīng)用。 - 大規(guī)模應(yīng)用:WebSocket適用于復(fù)雜的、大規(guī)模的實時應(yīng)用,如在線游戲、協(xié)同編輯等。
WebSocket 的缺點
- 復(fù)雜性:WebSocket協(xié)議的握手過程相對復(fù)雜,需要服務(wù)器和客戶端實現(xiàn)特定的協(xié)議邏輯。
- 難以穿越防火墻和代理服務(wù)器:WebSocket的特殊協(xié)議可能會受到防火墻和代理服務(wù)器的限制。
總結(jié)
EventSource
是 HTML5
中一個強大的 API
,提供了簡單可靠的服務(wù)器推送機制,用于實現(xiàn)實時通信。
與 WebSocket
相比,EventSource
的優(yōu)勢在于其簡單易用、自動重連、輕量級和跨域支持。然而,它也有一些限制,如單向通信和較低的瀏覽器支持。相比之下,WebSocket
適用于雙向通信、大規(guī)模應(yīng)用和實時性要求較高的場景,但其復(fù)雜性和穿越防火墻的挑戰(zhàn)也需要考慮。文章來源:http://www.zghlxwxcb.cn/news/detail-499616.html
總的來說,EventSource
是一種非常有用的 API
,適用于許多實時應(yīng)用場景,如實時股票報價、即時聊天、實時通知等。它提供了一種簡單而可靠的方式來建立服務(wù)器推送連接,并實現(xiàn)實時更新和通知。如果應(yīng)用程序只需要服務(wù)器向客戶端單向推送數(shù)據(jù),EventSource
是一個不錯的選擇。然而,如果需要雙向通信或更高級的實時功能,WebSocket
可能更適合。文章來源地址http://www.zghlxwxcb.cn/news/detail-499616.html
參考
- Mozilla Developer Network (MDN) - EventSource
- Stream Updates with Server-Sent Events
到了這里,關(guān)于實時通信的服務(wù)器推送機制 EventSource(SSE) 簡介,附 go 實現(xiàn)示例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!