前端 SSE 实战应用:用最简单的方式实现实时推送

前端 SSE 实战应用:用最简单的方式实现实时推送

📌 点赞收藏关注不迷路!
在前端项目中,我们常听到“实时通信”这个需求 —— 聊天、进度、状态变化、系统消息。

但提到实时,大家首先想到的是 WebSocket,对吧?

其实还有一种更轻量、简单、优雅的实时推送方案,那就是:

SSE(Server-Sent Events)

本文将带你深入理解并实战实现一个前端 SSE 应用,包括:

  • 什么是 SSE,它与 WebSocket、轮询的区别
  • 如何在 Vue / 原生项目中接入 SSE
  • 封装一个稳定的 useSSE Hook
  • 前后端完整交互示例:推送进度条、系统消息
  • 使用中断、自动重连、心跳优化技巧

🌟 一、什么是 SSE?和 WebSocket 有什么区别?

SSE(Server-Sent Events) 是 HTML5 标准中的一种服务端推送技术,通过 EventSource 对象与服务端建立单向持久连接,服务器可以持续向客户端推送事件数据。

特性SSEWebSocket轮询
连接方向单向(服务端 → 客户端)双向(全双工)客户端轮询请求服务端
实现复杂度⭐ 很简单较复杂(需协议握手)简单但浪费资源
兼容性Chrome / Firefox / Safari全面全面
重连机制✅ 内置自动重连❌ 需手动实现无连接
使用场景状态推送、日志、监控通知聊天、游戏、协同编辑等简单数据刷新

🚀 二、前端如何使用 SSE?基础示例

SSE 的核心是 EventSource 对象:

const source = new EventSource('/sse')source.onmessage = (event) => {console.log('收到消息:', event.data)
}source.onerror = (err) => {console.error('连接异常:', err)
}

📌 onmessage 是默认事件监听,也可以监听自定义事件:

source.addEventListener('progress', (e) => {console.log('任务进度:', e.data)
})

⚙️ 三、SSE 服务端返回格式

服务端 SSE 响应格式必须是 text/event-stream,并遵循以下格式:

event: progress
data: 任务已完成 40%
\n

关键点:

  • 必须设置响应头:Content-Type: text/event-stream
  • 每条消息以 \n\n 结束
  • 支持 id: xxxretry: 5000 设置消息 ID 和重连时间

🔧 四、Vue 中封装 useSSE Hook(支持断开/重连)

// useSSE.ts
import { ref, onUnmounted } from 'vue'export function useSSE(url: string) {const data = ref<string | null>(null)const connected = ref(false)let source: EventSource | null = nullconst connect = () => {if (source) source.close()source = new EventSource(url)connected.value = truesource.onmessage = (event) => {data.value = event.data}source.onerror = () => {connected.value = falsesource?.close()// 自动尝试重连由 EventSource 自带实现}}const close = () => {source?.close()connected.value = false}onUnmounted(() => {close()})return {data,connected,connect,close,}
}

🧪 五、前后端实战:实时推送任务进度条

✅ 后端示例(Node.js + Express)

// server.js
import express from 'express'
const app = express()app.get('/sse', (req, res) => {res.setHeader('Content-Type', 'text/event-stream')res.setHeader('Cache-Control', 'no-cache')res.setHeader('Connection', 'keep-alive')let progress = 0const timer = setInterval(() => {progress += 10res.write(`event: progress\ndata: ${progress}\n\n`)if (progress >= 100) clearInterval(timer)}, 1000)req.on('close', () => {console.log('客户端断开连接')clearInterval(timer)})
})app.listen(3000, () => {console.log('SSE 服务器已启动: http://localhost:3000/sse')
})

✅ 前端页面

<template><div><p>当前进度:{{ data }}</p><button @click="connect">开始监听</button><button @click="close">断开连接</button></div>
</template><script setup lang="ts">
import { useSSE } from './composables/useSSE'const { data, connect, close } = useSSE('http://localhost:3000/sse')
</script>

🛡 六、SSE 最佳实践建议

✅ 建议:

  • 为每条消息设置 event:,区分不同事件类型
  • 每条消息设置 id:,支持客户端断线重连后定位
  • 长连接可设置 retry:,客户端自动重连间隔
  • 可加入心跳机制(如每 30 秒发一次 ping)

🔄 七、如果你想手动重连

虽然浏览器自带 SSE 自动重连机制,但你也可以自己控制:

source.onerror = () => {console.log('断线,5秒后重连')setTimeout(connect, 5000)
}

🧠 八、适合用 SSE 的场景有哪些?

场景推荐使用
后台任务进度
系统消息通知
数据监控/实时日志
聊天/游戏等双向通信❌(建议 WebSocket)

✅ 最后说一句

SSE 是一种 简单但不简单的技术,适合用在轻量推送、状态更新、进度条展示等场景。

不需要额外库,不需要双向握手,一行代码就能接收服务端实时推送!

如果你觉得这篇文章有帮助,别忘了点个 收藏 + 点赞 + 关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91690.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第16章 基于AB实验的增长实践——验证想法:AB实验实践

​一、AB实验全流程框架​实验分为5个核心环节&#xff1a;实验假设​ → 实验设计​ →实验运行​ → 实验分析​ → 实验决策​​二、各环节核心要点详解​​1. 实验假设​​原则​&#xff1a;目标性、可归因、可复用&#xff08;前两者必选&#xff09;​&#xff08;1&…

解决【软件安装路径】失败的方法

出现问题上图所示问题为&#xff1a;你的临时目录路径中包含 Unicode 字符&#xff0c;这可能会导致安装损坏。请参阅故障排除指南以获取解决方法。出现问题的原因&#xff1a;添加路径下存在中文&#xff0c;导致系统文件无法识别。解决方法步骤一&#xff1a;创建Temp(临时文…

FreeRTOS学习笔记——总览

考虑到RTOS能够提升单片机开发能力&#xff0c;也是开发复杂任务的必经之路&#xff0c;还是有必要学习的。 FreeRTOS教程多&#xff0c;免费开源&#xff0c;是个不错的选择。后续可以考虑继续学习RT-Thread等。 参考1&#xff1a;FreeRTOS(教程非常详细&#xff09;——作者&…

Clip微调系列:《coOp: learning to prompt for vision-language models》

论文链接&#xff1a;arxiv.org/pdf/2109.01134v1 推荐视频(clip_coop的代码逻辑讲解&#xff0c;代码简单&#xff0c;有助于理解)&#xff1a;CLIP和CoOp工作的简单Pytorch复现和理解_哔哩哔哩_bilibili 其他参考链接&#xff1a;CoOp - CLIP 自适应Prompt工程 【一】_coop…

[论文阅读] 人工智能 + 软件工程 | 开源软件中的GenAI自白:开发者如何用、项目如何管、代码质量受何影响?

开源软件中的GenAI自白&#xff1a;开发者如何用、项目如何管、代码质量受何影响&#xff1f; 论文&#xff1a;Self-Admitted GenAI Usage in Open-Source SoftwarearXiv:2507.10422 Self-Admitted GenAI Usage in Open-Source Software Tao Xiao, Youmei Fan, Fabio Calefato…

AI绘画版权问题全解析:你的作品真的属于你吗?

AI绘画版权问题全解析:你的作品真的属于你吗? 关键词:AI绘画、版权归属、生成式AI、训练数据、独创性、法律合规、知识产权 摘要:当你用MidJourney生成一张“赛博朋克风格的熊猫”,或用Stable Diffusion画出“梵高笔触的星空咖啡馆”时,你是否想过:这张图的版权属于你、…

深入理解Linux文件I/O:系统调用与标志位应用

目录 一、引入 二、标志位 1、什么是标志位&#xff1f; 2、标志位传递示例 输出结果分析 关键点解释 三、文件描述符(File Descriptor)&#xff08;先大概了解&#xff09; 四、接口介绍&#xff1a;open()函数 1、命令查看 2、头文件 3、函数原型 4、参数说明 …

海康线扫相机通过采集卡的取图设置

目录 1、扫描高度小于65000行 1.1 软触发 1、采集卡设置项 2、相机设置项 1.2 硬触发 1、采集卡设置项 2、相机设置项 2、扫描高度大于65000行 1.1 软触发 1、采集卡设置项 2、相机设置 1.2 硬触发 1、采集卡设置项 2、相机设置 2.1 帧扫描 2.2 行扫描 3、注意…

InfluxDB 3与Apache Parquet:打造高性能时序数据存储与分析解决方案

在当今数据驱动的时代&#xff0c;各行业产生的数据量呈爆炸式增长&#xff0c;如何高效存储和管理海量数据成为企业和开发者面临的重大挑战。对于时序数据而言&#xff0c;其具有数据量大、写入频繁、查询模式多样等特点&#xff0c;对存储系统的性能和效率提出了更高的要求。…

20250718-4-Kubernetes 应用程序生命周期管理-Pod对象:实现机制_笔记

一、Pod对象&#xfeff;&#xfeff;1. 资源共享实现机制1&#xff09;共享网络&#xfeff;基本概念实现方式&#xff1a;通过将业务容器网络加入到负责网络的容器&#xff08;infra container&#xff09;实现网络共享核心特点&#xff1a;共享网络协议栈&#xff08;包括TC…

防爆手机是什么?能用普通手机改装吗?

在石油开采平台的井架之上&#xff0c;在化工车间的反应釜旁&#xff0c;在煤矿深达千米的巷道中&#xff0c;一群特殊的工作人员正使用着看似普通的通讯设备。这些设备外壳上醒目的Ex防爆认证标志&#xff0c;揭示着其与众不同的身份——防爆手机。这类专为易燃易爆环境设计的…

gem install报错解析

报错内容 [rootlocalhost ~]# gem install bundler Fetching: bundler-2.6.9.gem (100%) ERROR: Error installing bundler:bundler requires Ruby version > 3.1.0. The current ruby version is 2.5.0.解决方案&#xff08;任选其一&#xff09; 这个错误表明你当前的 Ru…

css 如何实现大屏4个占位 中屏2个 小屏幕1个

1、 使用grid.container {display: grid;grid-template-columns: repeat(4, 1fr);gap: 20px;border: 1px solid red;width: 400px;height: 400px;}media (max-width: 768px) {.container {grid-template-columns: 1fr;}}media (min-width: 768px) and (max-width: 992px) {.con…

Redis学习系列之—— JDHotKey 热点缓存探测系统

一、为什么需要热点缓存探测 在回答这个问题前&#xff0c;我们先考虑一下&#xff1a;为什么光用 Redis 还不够&#xff0c;还需要使用本地缓存&#xff1f; 一般来说&#xff0c;Redis 集群的性能能抗住几十万并发&#xff0c;能够应付大部分情况。但对于一些头部 APP&#x…

Linux 安全加固

Linux 安全加固需要从​​用户权限、系统服务、网络防护、日志审计、文件系统、访问控制​​等多个维度入手&#xff0c;目标是减少攻击面、限制未授权访问、提升系统健壮性。以下是​​详细步骤实操示例​​&#xff0c;覆盖主流 Linux 发行版&#xff08;如 CentOS/Ubuntu&am…

【Docker#2】容器历史发展 | 虚拟化实现方式

一、前言 – 容器技术发展史 容器技术是现今计算技术的重要组成部分&#xff0c;其发展历程可以追溯到很早的计算机系统提供的进程隔离工具。以下是容器技术的发展历程&#xff0c;其中涵盖了从早期的进程隔离技术到现代云计算和云原生的演变&#xff1a; ① Jail 时代 1979 年…

React + Mermaid 图表渲染消失问题剖析及 4 种代码级修复方案

Mermaid 是一个流行的库&#xff0c;它可以将文本图表&#xff08;例如 graph LR; A-->B;&#xff09;转换为 SVG 图表。在静态 HTML 页面中&#xff0c;Mermaid 会查找 <pre class"mermaid"> 代码块&#xff0c;并在页面加载时将它们替换为渲染后的图表。它…

[Element]修改el-pagination背景色

[Element]修改el-pagination背景色 代码 <el-pagination:current-page.sync"queryParams.current":page-size.sync"queryParams.size":page-sizes"[10, 20, 50, 100]"layout"prev, pager, next, jumper, sizes":total"queryP…

Docker 可用镜像列表

Docker 镜像源列表&#xff08;7月15日更新-长期&免费&#xff09;_dockerhub国内镜像源列表-CSDN博客

低代码可视化工作流的系统设计与实现路径研究

一、背景分析在数字化转型不断深化的背景下&#xff0c;企业业务流程呈现出高度定制化与动态调整的趋势&#xff0c;传统信息系统在开发周期、实施成本与扩展能力上的局限性日益凸显&#xff0c;已难以支撑快速响应和敏捷迭代的实际需求。面向这一现实挑战&#xff0c;基于 BPM…