传统的 Web 通信中局限性
在传统的 Web 通信中,客户端向服务器发送请求,服务器处理请求后返回响应,这种模式是一种单向的、被动的交互方式。例如,在一个新闻网站中,用户需要手动刷新页面才能获取最新的新闻内容。
对于一些实时性要求较高的应用场景,如在线聊天、股票行情展示、实时监控等,传统模式无法及时更新信息,用户体验较差。因为服务器不能主动向客户端发送数据,客户端只能不断地轮询服务器来获取最新信息,这会增加服务器的负载和网络流量,并且存在一定的延迟。
SSE概念
SSE(Server - Sent Events)是一种允许服务器向客户端发送实时更新的 Web 技术。它基于 HTTP 协议,通过建立一个持久的 HTTP 连接,服务器可以在有新数据时随时向客户端发送消息。与传统的请求 - 响应模式不同,SSE 是单向的,即服务器向客户端发送数据,客户端只能接收。例如,一个天气预报网站可以使用 SSE 技术,服务器在天气数据更新时主动将新的天气信息推送给客户端。
SSE和Websocket的对比
连接方式
SSE 基于 HTTP 协议,是单向连接,服务器向客户端发送数据。而 WebSocket 是全双工的,客户端和服务器可以同时发送和接收数据。例如,在一个在线聊天应用中,WebSocket 可以让双方实时交流,而 SSE 更适合服务器向客户端推送新闻、通知等单向信息。
协议复杂度
SSE 的实现相对简单,因为它基于 HTTP 协议,不需要额外的握手过程。WebSocket 需要进行专门的握手协议来建立连接,协议复杂度较高。
浏览器兼容性
SSE 具有较好的浏览器兼容性,大多数现代浏览器都支持。WebSocket 虽然也被广泛支持,但在一些旧版本的浏览器中可能存在兼容性问题。
正文开始
首先安装下express和cors,命令
npm install express
npm install cors
express 是一个基于 Node.js 平台,快速、轻量级且灵活的 Web 应用框架,广泛用于构建各种类型的 Web 应用和 API。
cors用来配置跨域
app.js服务端代码 (在终端执行命令 node app.js 启动服务),注意这里需要配置下端口,否则会有跨域问题。
javascript
const express = require('express');
const app = express();
const port = 3000;
// 引入 cors 模块
const cors = require('cors');
const corsOptions = {
//我这里端口号是5501,以本地实际端口为准
origin: 'http://127.0.0.1:5501',
};
// 使用 cors 中间件
app.use(cors(corsOptions));
// SSE 路由
app.get('/sse', (req, res) => {
// 设置响应头
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
// 模拟每隔 2 秒发送一次消息
const intervalId = setInterval(() => {
const message = `Data at ${new Date().toLocaleTimeString()}`;
res.write(`data: ${message}\n\n`);
}, 2000);
// 当客户端断开连接时,清除定时器
req.on('close', () => {
clearInterval(intervalId);
});
});
// 静态文件服务
app.use(express.static('public'));
// 启动服务器
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
前端代码(这里使用原生js来演示),在项目同级目录下创建public.html文件,使用liveServer启动即可
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Demo</title>
</head>
<body>
<h1>Server-Sent Events Demo</h1>
<ul id="messages"></ul>
<script>
// 127.0.0.1 这是一个特殊的 IP 地址,也被称为"回环地址",它始终指向本地主机(由于是本
//地启动的所以使用该Ip地址,在正式开发中替换成服务器地址)
const eventSource = new EventSource('http://127.0.0.1:3000/sse');
const messagesList = document.getElementById('messages');
eventSource.onmessage = (event) => {
//使用js创建li元素并插入ul中
const listItem = document.createElement('li');
listItem.textContent = event.data;
messagesList.appendChild(listItem);
};
eventSource.onerror = (error) => {
console.error('EventSource failed:', error);
};
</script>
</body>
</html>
运行效果

end