使用node.js来实现SSE服务端向客户端推送消息

传统的 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

相关推荐
木西4 小时前
告别机械重复:使用 Node.js + Playwright 构建 24 小时全自动测试网领水脚本
前端·javascript·node.js
xiaofeichaichai5 小时前
Vite原理与Webpack对比
前端·webpack·node.js
万亿少女的梦16810 小时前
基于Node.js和Express的旅游信息管理平台设计与开发
mysql·node.js·express·系统设计·旅游信息管理
hoLzwEge1 天前
Volta实战:项目级Node版本管理 + 自定义安装目录
前端框架·node.js
laowang3571 天前
依赖故障时,日志体系需要埋哪些关键节点才能快速定位是安装失败、解析失败还是运行时缺失?
前端·javascript·vue.js·webpack·node.js
不正经开发者1 天前
Node.js process
node.js
志尊宝1 天前
Vue3 环境搭建 + 第一个 HelloVue 项目(零基础入门)
vue.js·node.js·vue·css3
张一根2 天前
ESP32+Mqtt+Node.js+Vue3 做工控界面
node.js
TE-茶叶蛋2 天前
Node.js-Phase 1 学习总结:CLI 文件管理系统
学习·node.js
前端之虎陈随易3 天前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js