使用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

相关推荐
李游Leo1 小时前
安装 Node.js 和配置 cnpm 镜像源
npm·node.js
穗余12 小时前
NodeJS全栈开发面试题讲解——P2Express / Nest 后端开发
前端·node.js
橘子味的冰淇淋~13 小时前
npm run build 报错:Some chunks are larger than 500 KB after minification
前端·npm·node.js
穗余15 小时前
NodeJS全栈开发面试题讲解——P7 DevOps 与部署和跨域等
前端·面试·node.js
贩卖纯净水.15 小时前
邂逅Webpack和打包过程
前端·webpack·node.js
胡桃夹夹子16 小时前
【前端优化】使用speed-measure-webpack-plugin分析前端运行、打包耗时,优化项目
前端·webpack·node.js
穗余17 小时前
NodeJS全栈开发面试题讲解——P1Node.js 基础与核心机制
node.js
red润19 小时前
放弃 tsc 使用 tsx 构建Node 环境下 TypeScript + ESM 开发环境搭建指南
前端·typescript·node.js
我怎么能这么帅气21 小时前
Node定时器集体罢工!深挖事件循环中那些"时间刺客"
前端·javascript·node.js
我怎么能这么帅气21 小时前
Node.js原型污染:你的JSON.parse正在被下毒!
前端·javascript·node.js