文章目录
- 1、SSE 流式传输
- 2、后端代码
- 3、前端代码
- 5、SSE和WS 对比
- 6、chatgpt SSE的服务端返回的数据
- 参考链接
单工通信是一种
单向
的通信方式,其中信息只能从发送端传输到接收端,而接收端不能向发送端发送任何信息
。在Web开发中,Server-Sent Events (SSE) 是一种实现单工通信的技术,允许服务器
将更新数据推送到客户端
1、SSE 流式传输
SSE是一种由HTML5引入的技术,用于在服务器和浏览器之间创建持久的单向连接。通过这种连接,
服务器可以不断地向浏览器推送数据
,而不需要客户端轮询
服务器以获取更新。SSE使用HTTP协议,并且在浏览器端使用EventSource对象
来接收服务器发送的事件。
chatgpt
的 问题回答, 就是用的这种方式
- 优点:
- 简单易用,使用标准HTTP协议。
- 在许多现代浏览器中都有良好的支持。
- 对于
实时更新
的应用,如新闻推送、股票行情、聊天系统、倒计时同步、实时天气等非常适用。
- 缺点:
单向通信
,客户端无法向服务器发送数据(适合使用WebSocket)。- 不适合传输大量数据或需要双向通信的应用。
2、后端代码
- 采用
express
起一个服务 - 用
cors
处理跨域问题 - 设置SSE 技术必要的响应头
在向前端传输数据的时候, res.write 里面的东西 如若有变量啥的,一定要转化成字符串
SSE 响应
主要由一系列以两个换行符分隔
的事件组成。每个事件可以包含以下字段:
data
:事件的数据。如果数据跨越多行,每行都应该以data:开始。- id:事件的唯一标识符。客户端可以使用这个ID来恢复事件流。
- event:自定义事件类型。客户端可以根据不同的事件类型来执行不同的操作。
- retry:建议的重新连接时间(毫秒)。如果连接中断,客户端将等待这段时间后尝试重新连接。
const express = require("express");
const cors = require("cors");const app = express();app.use(cors());
function formatDate() {const now = new Date();const year = now.getFullYear();const month = now.getMonth() + 1; // getMonth() 返回 0-11,需要 +1const day = now.getDate();const hours = now.getHours();const minutes = now.getMinutes();const seconds = now.getSeconds();return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}app.use(express.static("public"));app.get("/events", function (req, res) {// 必要的一些响应头配置res.setHeader("Content-Type", "text/event-stream");res.setHeader("Cache-Control", "no-cache");res.setHeader("Connection", "keep-alive");res.header("Access-Control-Allow-Origin", "*"); // 允许所有来源let count = 1;let intervalInstance = setInterval(() => {if (count == 10) {res.write(`data:${JSON.stringify({data: formatDate(),count: count,})}\n\n`); // 发送一个特殊事件通知客户端关闭res.end();clearInterval(intervalInstance);return;}res.write(`data: ${JSON.stringify({data: formatDate(),count: count,})}\n\n`);count++;}, 2000);
});app.listen(3000, () => {console.log(`http://localhost:3000`);
});
3、前端代码
每次接收后端返回值结构如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title></title>
</head><body><h1>Server-SentEvents</h1><div id="container"></div><script>const evtSource = new EventSource("http://127.0.0.1:3000/events");const container = document.getElementById("container");evtSource.onmessage = function (event) {console.log(event, JSON.parse(event.data));let data = JSON.parse(event.data)if (data.count == 10) {evtSource.close();}const pEl = document.createElement("p");pEl.innerHTML = data.data + ' 次数' + data.countcontainer.appendChild(pEl);};</script>
</body></html>
##4、实际效果
5、SSE和WS 对比
WebSocket:是
全双工通信
特性/因素 | SSE | WS(WebSocket) |
---|---|---|
协议 | 基于HTTP,使用标准HTTP连接 | 单独的协议(ws:// 或 wss://),需要握手升级 |
通信方式 | 单向通信(服务器到客户端) | 全双工通信 |
数据格式 | 文本(UTF-8编码) | 文本或二进制 |
重连机制 | 浏览器自动重连 | 需要手动实现重连机制 |
实时性 | 高(适合频繁更新的场景) | 非常高(适合高度交互的实时应用) |
浏览器支持 | 良好(大多数现代浏览器支持) | 非常好(几乎所有现代浏览器支持) |
适用场景 | 实时通知、新闻feed、股票价格等需要从服务器推送到客户端的场景 | 在线游戏、聊天应用、实时交互应用 |
复杂性 | 较低,易于实现和维护 | 较高,需要处理连接的建立、维护和断开 |
兼容性和可用性 | 基于HTTP,更容易通过各种中间件和防火墙 | 可能需要配置服务器和网络设备以支持WebSocket |
服务器负载 | 适合较低频率的数据更新 | 适合高频率消息和高度交互的场景 |
6、chatgpt SSE的服务端返回的数据
这里他其实返回的是
unicode
编码的字符
参考链接
- Unicode在线互转
- EventSource DMN 官方文档