当前位置: 首页 > ds >正文

前端 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.xdnf.cn/news/15886.html

相关文章:

  • Android CountDownTimer
  • 深入理解Linux文件I/O:系统调用与标志位应用
  • 机器学习17-Mamba
  • c++继承详解
  • 【Leecode 随笔】
  • 使用python的读取xml文件,简单的处理成元组数组
  • 【时时三省】(C语言基础)通过指针引用字符串
  • PyCharm 高效入门指南(核心模块详解二)
  • stm32f4 dma的一些问题
  • API和SDK有何区别??
  • 跨平台猫咪键盘桌宠BongoCat v0.6.2 绿色版(附带多款皮肤包)
  • SDIO协商,枚举,CMD等概念
  • [特殊字符] Spring Boot 常用注解全解析:20 个高频注解 + 使用场景实例
  • 前端篇——番外篇 Bootstrap框架
  • (笔记+作业)第五期书生大模型实战营---L2G2000 GraphGen:训练数据合成实践
  • 前端之CSS
  • LP-MSPM0G3507学习--04GPIO控制
  • 磁悬浮转子不平衡质量的高精度控制:从原理到实战
  • 一文讲清楚React的render优化,包括shouldComponentUpdate、PureComponent和memo
  • Android音视频探索之旅 | Webrtc 1对1音视频通话核心流程分析
  • 借助AI学习开源代码git0.7之三git-init-db
  • YOLO演变史(一)
  • CSS样式中的布局、字体、响应式布局
  • CMakeLists.txt 配置文件
  • 非线性优化相关库笔记
  • 【面试题】大厂高压面经实录丨第二期
  • @Qualifier(“beanName“) 详解
  • 一个逻辑问题
  • 《设计模式之禅》笔记摘录 - 8.命令模式
  • Day06_C语言网络编程20250718mobus重点