1前言
目前JS实时通信方式主要由:websocket、socket.io、eventSource(SSE)这三种方式。有人就也许好奇有了websocket这种实时通信方式,为啥还需要eventSource呢?这是因为不同客户端场景,有着各自的优势。
eventSource是单向通信,而websocket是双向通信。在新闻推送、股票行情这种只需要服务器发送消息给客户端场景,使用SSE更加合适,另外SSE是使用HTTP传输的。而websocket要求全双工连接和一个新的websocket服务器去处理,
因为各有所长,我们只需要根据实际应用场景,去选择最优的应用方案。
2介绍
EventSource 对象接口用于接收服务器发送的事件。它通过 HTTP 连接到服务器,已 text/event-stream
格式接收事件,不关闭连接。
EventSource 对象主要用于 Server-Sent Events(简称 SSE)的技术。这是一种能让浏览器通过 HTTP 连接自动收到服务器端更新的技术。
这个技术的作用是可以完成从服务器端到客户端(浏览器)单向的消息传递。因此我们可以用这个来做推送。
相关文档:https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource
2.1浏览器兼容性

2.2构造函数
const eventSource = new EventSource()
2.3属性
说明 | 属性 |
---|---|
onerror | 当发生错误时被调用,并且在此对象上派发 error 事件 |
onmessage | 服务器端发送给客户端一条消息时触发 |
onopen | SSE 连接刚打开时触发 |
readyState | 表示连接状态(CONNECTING 、OPEN 和 CLOSED ) |
url | 代表源头的 URL |
2.4方法
方法 | 说明 |
---|---|
close | 关闭连接 |
2.5通信过程
在浏览器通信截图:
2.6服务端
服务端返回响应头必须包含以下header:
Content-Type: text/event-steam
Cache-Control: no-cache
Connection: keep-alive
服务器返回的数据格式为文本型,由若干个message组成,每个message用\n\n分割
每个message内容是[key]:value
key有四种情况:id、event(type)、data、tetry
-
id 为每个返回数据的唯一标识,浏览器用lastEventId读取id,一旦连接断开,浏览器会从新发送http请求,带有特殊请求头Last-Event-Id,代表断开时的id,用于建立重新连接,属于一种重连的同步机制.
-
data 数据内容一般放于data字段。
-
event(type):消息类型,一般默认为message,服务端可以自定义,前端用addEventListener()监听。
-
retry:代表服务器重新发送请求的间隔时间。
3实例运用
3.1原生EventSource
/*
* new EventSource(url, configuration)
* url:请求地址路径
* configuration 可选项:withCredentials,默认为false,指是否CORS设置
*
*/
const eventSource = new EventSource('/api/stream');
// 正常的EventSource,我们只关心以下三个事件
/*
* open:订阅成功(和后端连接成功)
*/
eventSource.addEventListener("open", function(e) {
console.log('open successfully')
})
/*
* message:后端返回信息,格式可以和后端协商
*/
eventSource.addEventListener("message", function(e) {
console.log(e.data)
})
/*
* error:错误(可能是断开,可能是后端返回的信息)
*/
eventSource.addEventListener("error", function(err) {
console.log(err)
// 类似的返回信息验证,这里是实例
err && err.status === 401 && console.log('not authorized')
})
// 需要关闭了
eventSource.close()
注意:因为原生EventSource无法进行自定义配置,例如header、method等,因此我们需要引用其他的封装库
3.2fetch-event-source
使用post的方式请求eventSource
安装依赖:npm install --save @rangermauve/fetch-event-source
import { fetchEventSource } from '@microsoft/fetch-event-source'
fetchEventSource('/api/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(dataJson),
onopen() {},
onmessage(event) {
const jsonData = JSON.parse(event.data)
let respondTexts = jsonData.delta
let finishStatus = jsonData.finished
},
onerror() {},
onclose() {}
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律