EventSource 使用
约 1276 字大约 4 分钟
2025-01-21
EventSource
是一种Server-Sent Events (SSE)
技术。
浏览器通过发送 HTTP GET
请求到服务器上特定的 SSE
端点,然后服务器通过该连接发送事件(event
)和相关数据到客户端,故 SSE
只能使用 GET
请求。
注意 EventSource
不支持发送请求头,如果需要发送请求头则要用EventSourcePolyfill
。
安装
EventSource
是一个原生的浏览器 API,不需要安装任何额外的库。但是,如果你需要在不支持 EventSource
的浏览器中使用它,可以使用 event-source-polyfill
库。
event-source-polyfill
是一个 polyfill,它提供了一个 EventSource
的实现,可以在不支持原生 EventSource
的浏览器中使用。
pnpm
$ pnpm add -D event-source-polyfill
yarn
$ yarn add event-source-polyfill
npm
$ npm install event-source-polyfill
使用
EventSource
具有端口重试机制,如果连接失败,会自动重试,直到连接成功为止。EventSource
需要主动close
才能关闭,可以在业务层确定关闭时机。
EventSource
const url = ''
const sse = new EventSource(url);
/*
* 这将仅监听类似下面的事件
*
* event: notice
* data: useful data
* id: someid
*/
sse.addEventListener("notice", (e) => {
console.log(e.data);
});
/*
* 同理,以下代码将监听具有字段 `event: update` 的事件
*/
sse.addEventListener("update", (e) => {
console.log(e.data);
});
/*
* “message”事件是一个特例,因为它可以捕获没有 event 字段的事件,
* 以及具有特定类型 `event:message` 的事件。
* 它不会触发任何其他类型的事件。
*/
sse.addEventListener("message", (e) => {
console.log(e.data);
});
EventSourcePolyfill
前面也提过EventSource
不支持发送请求头,如果需要发送请求头则要用EventSourcePolyfill
。
import EventSource from 'event-source-polyfill';
// 创建 EventSourcePolyfill连接,如果不需要发送请求头可以使用EventSource即可
const eventSource = new EventSourcePolyfill('url',
{
headers:{
"Content-Type": 'application/json'
}
}
)
// 处理 SSE 消息
eventSource.onmessage = function (event) {
console.log('接收SSE的消息:', event.data)
// 在这里处理接收到的流式数据
}
// 处理 SSE 连接打开事件
eventSource.onopen = function (event) {
console.log('SSE连接完成:', event)
}
// 处理 SSE 连接关闭事件
eventSource.onclose = function (event) {
console.log('SSE连接关闭:', event)
}
// 处理 SSE 错误事件
eventSource.onerror = function (error) {
console.error('SSE EventSource error:', error)
}
// 可以在合适的时机关闭
// eventSource.close()
优缺点
优点
- 单向通信:
EventSource
是服务器向客户端的单向通信,客户端接收来自服务器的事件流。 - 基于
HTTP
协议:EventSource
基于标准的HTTP/HTTPS
协议,使用长轮询或类似的机制,但并不是完全双向的通信。 - 文本数据传输: 通常用于传输文本数据,如服务器推送的消息或事件。
- 自动重连:当连接中断,
EventSource
会自动尝试重新连接,不需要手动处理重连。
缺点
- 只能使用
GET
请求发起,参数将暴露。只能选择使用EventSourcePolyfill
在header
传递一些参数。 - 因为有自动重连所以,只能主动关闭,这需要业务层去控制关闭时机。对应一个长期使用的
EventSource
这不是一个问题。
EventSource与WebSocket区别
EventSource
和 WebSocket
是两种用于实现实时通信的技术,但在功能和应用场景上有一些明显的区别。最大的不同就是,EventSource
是单向通信(消息只能从服务端到发送到客户端),而 WebSocket
是双向通信。
EventSource
- 单向通信: EventSource 是服务器向客户端的单向通信,客户端接收来自服务器的事件流。
- 基于HTTP协议: EventSource 基于标准的 HTTP/HTTPS 协议,使用长轮询或类似的机制,但并不是完全双向的通信。
- 文本数据传输: 通常用于传输文本数据,如服务器推送的消息或事件。
- 自动重连: 当连接中断,EventSource 会自动尝试重新连接,不需要手动处理重连。
- 适用场景: 适用于服务器向客户端单向推送信息,比如实时更新的新闻、股票报价等,但不适合需要客户端与服务器进行双向通信的场景。
WebSocket
- 双向通信: WebSocket 提供全双工、双向通信的能力,客户端和服务器之间可以互相发送数据。
- 独立的协议: WebSocket 使用自己的协议,建立在 TCP 连接之上,允许在同一个连接上进行双向通信。
- 任意数据传输: 能够传输任意类型的数据,不限于文本,可以是二进制数据。
- 手动处理重连: 当连接中断,需要在客户端代码中实现重新连接的逻辑。
- 适用场景: 适用于需要双向实时通信的场景,比如聊天应用、在线游戏等,其中客户端和服务器都需要发送和接收数据。
EventSource
更适用于服务器向客户端的单向通信,而 WebSocket
则适合需要客户端和服务器双向实时通信的场景。选择使用哪种技术取决于你的具体需求和应用场景。