SSE(Server-Sent Events)服务端推送技术

什么是SSE(Server-Sent Events)?

  • Server-Sent Events是轻量级的服务端推送方案,即 Server -----> Client

在某些情况下,前端需要持续接受后端的数据更新,通常有两种方案:

1、客户端(前端)拉取:以一定时间间隔向服务器发送请求更新;例如:轮训,长轮训

2、服务端推送:服务端主动将更新数据推送给客户端(前端);例如:WebSocket, SSE

众所周知,WebSocket是我们所了解的双向通讯领域中的王者🔱,它广泛应用于双向实时通信领域。然而在实时通讯领域中还有一种单向的服务端通讯技术,可以更加轻量级别的代替WebSocket在日常生活中的满足只服务端给客户端推送数据的需求,减少双向通讯带来的不必要的资源消耗。它就是SSE服务端推送技术,满足服务端给客户端推送数据,并且只通过HTTP建立连接。例如:股票📈k线的实时变化,彩票趋势走向,以及工业数据实时监控(受限于页面的数据获取范围面)和日志推送和CI/CD工作流进度的推送等相关单向推送需求的场景。

当前时下最火的ChatGPT(OpenAI)的交互效果也是给予SSE技术实现的。OpenAI基于大模型需要有一定时间进行算法分析,并不能像我们服务接口一样直接返回所有数据,故采用这种持续返回数据的方式,避免用户界面等待太久出现空白的现象。

SSE的使用

SSE用于向浏览器客户端发送持续消息或者连续数据流, 并通过名为EventSource的javaScript的API来增强原声、跨浏览器的流式传输

针对现代浏览器,需要考虑兼容性问题。

原生客户端代码

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SSE Demo</title>
</head>
<body>
<h1>SSE Demo</h1>
<button onclick="connectSSE()">建立 SSE 连接</button>
<button onclick="closeSSE()">断开 SSE 连接</button>
<br />
<br />
<div id="message"></div>
​
<script>
    const messageElement = document.getElementById('message')
​
    let eventSource
​
    // 建立 SSE 连接
    const connectSSE = () => {
        eventSource = new EventSource('http://127.0.0.1:3005/xxx/stream')
​
        // 监听消息事件
        eventSource.addEventListener('message', (event) => {
            const data = JSON.parse(event.data)
            // 服务端推送的数据
            console.log(data, '######')
            messageElement.innerHTML += `${data.msg}` + '<br />'
        })
​
        eventSource.onopen = () => {
            messageElement.innerHTML += `SSE 连接成功,状态${eventSource.readyState}<br />`
        }
​
        eventSource.onerror = () => {
            messageElement.innerHTML += `SSE 连接错误,状态${eventSource.readyState}<br />`
        }
    }
​
    // 断开 SSE 连接
    const closeSSE = () => {
        eventSource.close()
        messageElement.innerHTML += `SSE 连接关闭,状态${eventSource.readyState}<br />`
    }
</script>
</body>
</html>

服务端代码:(采用的是nest.js框架的@Sse装饰器实现)

typescript 复制代码
@Sse('stream')
  stream() {
    return new Observable((observer) => {
      observer.next({ data: { msg: 'aaa'} });
​
      setInterval(() => {
        observer.next({ data: { msg: 'bbb'} });
      }, 2000);
​
      setInterval(() => {
        observer.next({ data: { msg: 'ccc'} });
      }, 5000);
    });
  }

以上的两个前端代码和后端代码可以进行sse推送演示

  • sse还可以应用于很多实时更新的场所

    1、实时新闻更新

    2、股市行情

    3、地图上的位置跟踪

    4、社交媒体的站内信推送,关注、点赞和评论推送

    5、游戏的各种活动推送

    6、用户运营消息推送

不过很多企业现在都适用三方推送技术,例如:极光推送、个推和goEasy等。

SSE使用的注意事项

1、首先,设置SSE相关的响应头(事件流、长连接、chunk传输-事件自带、禁用缓存)

2、其次,将数据封装为事件(event)按照一定格式发送给客户端

3、然后,设置适当的延迟和缓存控制发送时机(适用于动态生成内容和大数据传输)

4、最后再合适的时候断开客户端连接

SSE的优缺点(特性和限制)

1、sse是单向传输的, 消息数据是从服务端到客户端

2、如果不使用HTTP/2会受到最大连接数限制,浏览器对每个域名限制的的http连接数为6,这是跨标签的。HTTP/2默认是100。并且该问题在Chrome和Firefox中标记为无法修复

参考

一文读懂即时更新方案:SSE

Server-Sent Events服务器信息推送

Server-Sent Events:轻量级的服务端推送方案

推送数据?也许你不需要 WebSocket

Web 实时消息推送的 7 种实现方案

相关推荐
我不吃饼干9 天前
鸽了六年的某大厂面试题:你会手写一个模板引擎吗?
前端·javascript·面试
涵信9 天前
第一节 布局与盒模型-Flex与Grid布局对比
前端·css
我不吃饼干9 天前
鸽了六年的某大厂面试题:手写 Vue 模板编译(解析篇)
前端·javascript·面试
前端fighter9 天前
为什么需要dependencies 与 devDependencies
前端·javascript·面试
你的人类朋友9 天前
(●'◡'●)从Dockerfile快速入门Docker Compose
后端
veminhe9 天前
HTML5 浏览器支持
前端·html·html5
前端fighter9 天前
Vuex 与 Pinia:全面解析现代 Vue 状态管理的进化之路
前端·vue.js·面试
GetcharZp9 天前
「神器推荐」Rclone:轻松玩转云端存储,FTP 也能飞起来!
后端
华子w9089258599 天前
基于 SpringBoot+JSP 的医疗预约与诊断系统设计与实现
java·spring boot·后端
舒一笑9 天前
工作流会使用到Webhook是什么
后端·程序员