重学SSE

简介: 重学SSE

概述

SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。

SSE 和 Socket 区别

SSE(Server-Sent Events)和 WebSocket 都是实现服务器向客户端实时推送数据的技术,但它们在某些方面还是有一定的区别。

  1. 技术实现

SSE 基于 HTTP 协议,利用了其长连接特性,通过浏览器向服务器发送一个 HTTP 请求,建立一条持久化的连接。而 WebSocket 则是通过特殊的升级协议(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 连接,与传统 HTTP 连接不同。

  1. 数据格式

SSE 可以传输文本和二进制格式的数据,但只支持单向数据流,即只能由服务器向客户端推送数据。WebSocket 支持双向数据流,客户端和服务器可以互相发送消息,并且没有消息大小限制。

  1. 连接状态

SSE 的连接状态仅有三种:已连接、连接中、已断开。连接状态是由浏览器自动维护的,客户端无法手动关闭或重新打开连接。而 WebSocket 连接的状态更灵活,可以手动打开、关闭、重连等。

  1. 兼容性

SSE 是标准的 Web API,可以在大部分现代浏览器和移动设备上使用。但如果需要兼容老版本的浏览器(如 IE6/7/8),则需要使用 polyfill 库进行兼容。而 WebSocket 在一些老版本 Android 手机上可能存在兼容性问题,需要使用一些特殊的 API 进行处理。

  1. 安全性

SSE 的实现比较简单,都是基于 HTTP 协议的,与普通的 Web 应用没有太大差异,因此风险相对较低。WebSocket 则需要通过额外的安全措施(如 SSL/TLS 加密)来确保数据传输的安全性,避免被窃听和篡改,否则可能会带来安全隐患。

总体来说,SSE 和 WebSocket 都有各自的优缺点,适用于不同的场景和需求。如果只需要服务器向客户端单向推送数据,并且应用在前端的浏览器环境中,则 SSE 是一个更加轻量级、易于实现和维护的选择。而如果需要双向传输数据、支持自定义协议、或者在更加复杂的网络环境中应用,则 WebSocket 可能更加适合。

适用于场景

chatGPT 返回的数据 就是使用的SSE 技术

实时数据大屏 如果只是需要展示 实时的数据可以使用SSE技术 而不是非要使用webSocket

API 用法

EventSource 对象是 HTML5 新增的一个客户端 API,用于通过服务器推送实时更新的数据和通知。在使用 EventSource 对象时,可以通过以下方法进行配置和操作:

1. EventSource() 构造函数

EventSource 的构造函数接收一个 URL 参数,通过该 URL 可以建立起与服务器的连接,并开始接收服务器发送的数据。

const eventSource = new EventSource(url, options);
  • url:String 类型,表示与服务器建立连接的 URL。必填。
  • options:Object 类型,表示可选参数。常用的可选参数包括:
  • withCredentials:Boolean 类型,表示是否允许发送 Cookie 和 HTTP 认证信息。默认为 false。
  • headers:Object 类型,表示要发送的请求头信息。
  • retryInterval:Number 类型,表示与服务器失去连接后,重新连接的时间间隔。默认为 1000 毫秒。

示例:

const eventSource = new EventSource('/my-server');
2. EventSource.readyState 属性

readyState 属性表示当前 EventSource 对象的状态,它是一个只读属性,它的值有以下几个:

  • CONNECTING:表示正在和服务器建立连接。
  • OPEN:表示已经建立连接,正在接收服务器发送的数据。
  • CLOSED:表示连接已经被关闭,无法再接收服务器发送的数据。

示例:

if (eventSource.readyState === EventSource.CONNECTING) {
  console.log('正在连接服务器...');
} else if (eventSource.readyState === EventSource.OPEN) {
  console.log('已经连接上服务器!');
} else if (eventSource.readyState === EventSource.CLOSED) {
  console.log('连接已经关闭。');
}
3. EventSource.close() 方法

close() 方法用于关闭 EventSource 对象与服务器的连接,停止接收服务器发送的数据。

eventSource.close();
4. EventSource.onopen 事件

onopen 事件表示 EventSource 对象已经和服务器建立了连接,并开始接收来自服务器的数据。当 EventSource 对象建立连接时,触发该事件。

eventSource.onopen = function(event) {
  console.log('连接成功!', event);
};
5. EventSource.onerror 事件

onerror 事件表示在建立连接或接收服务器数据时发生了错误。当出现错误时,触发该事件。

eventSource.onerror = function(event) {
  console.log('发生错误:', event);
};
6. EventSource.onmessage 事件

onmessage 事件表示已经接收到服务器发送的数据,当接收到数据时,触发该事件。

eventSource.onmessage = function(event) {
  console.log('接收到数据:', event);
};

以上就是 EventSource 对象的常用 API 介绍,需要注意的是,在使用 EventSource 对象的过程中,如果服务器没有正确地设置响应头信息(如:Content-Type: text/event-stream),可能会导致 EventSource 对象无法接收到服务器发送的数据。

nodejs 后端操作

import express from 'express';
const app = express();
app.get('/api/sse', (req, res) => {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream', //核心返回数据流
        'Connection': 'close'
    })
    const data = fs.readFileSync('./index.txt', 'utf8')
    const total = data.length;
    let current = 0;
    //mock sse 数据
    let time = setInterval(() => {
        console.log(current, total)
        if (current >= total) {
            console.log('end')
            clearInterval(time)
            return
        }
        //返回自定义事件名
        res.write(`event:lol\n`)
        /返回数据
        res.write(`data:${data.split('')[current]}\n\n`)
        current++
    }, 300)
})
app.listen(3000, () => {
    console.log('Listening on port 3000');
});

文本数据

悲索之人烈焰加身,堕落者 不可饶恕,我即是引路的灯塔,也是净化的清泉。
永恒燃烧的羽翼,带我脱离凡间的沉沦,圣火将你洗涤。
今由烈火审判,于光明中得救。
利刃在手,制裁八方!

前端调用

const sse = new EventSource('http://localhost:3000/api/sse' )
sse.addEventListener('open', (e) => {
    console.log(e.target)
})
//对应后端nodejs自定义的事件名lol
sse.addEventListener('lol', (e) => {
    console.log(e.data)
})

目录
相关文章
|
1月前
|
机器学习/深度学习 自然语言处理 网络协议
为什么ChatGPT采用SSE协议而不是WebSocket?
在探讨大型语言模型ChatGPT的技术实现时,一个引人注目的细节是其选择使用SSE(Server-Sent Events)协议而非WebSocket来实现数据的实时推送。这一选择背后,蕴含着对技术特性、应用场景及资源效率的深思熟虑。本文将深入探讨ChatGPT为何偏爱SSE,以及这一决策背后的技术逻辑。
51 2
|
4月前
|
编译器 图形学 C语言
SSE2 指令集简介以及与SSE的差别
SSE2,Intel在2001年为Pentium 4引入的扩展,增强了SSE的功能,添加了对双精度浮点和64位整数运算的支持,新增144条指令,提升向量处理能力。SSE2的C代码示例展示了如何通过`_mm_add_ps`加速向量加法。启用SSE2编译器支持可优化处理图像、音频和视频等大量计算任务的性能。
|
4月前
|
算法 程序员 数据处理
SSE - 多媒体编程中的利器 - SSE指令集简介和C代码示例
本文介绍了SSE(Stream SIMD Extensions)指令集在多媒体处理中的应用,它能提升浮点运算性能,尤其适合处理大量数据。SSE允许一次处理4个32位浮点数,提高效率。文中通过示例展示了如何在C++中集成SSE,比如使用`__m128`数据类型和`_mm_set_ps1()`等函数优化浮点数放大算法。测试结果显示,使用SSE优化后的算法比未优化版本快约3倍,强调了SSE在高效处理多媒体数据中的价值。
|
4月前
|
机器学习/深度学习 并行计算 编译器
AVX 指令集简介及其与 SSE 的对比
本文介绍了AVX指令集在高性能计算中的重要性,它是Intel于2011年推出的一种SIMD技术,扩展了SSE指令集,将向量宽度增至256位,支持更多数据类型和浮点精度控制。主要差异包括向量宽度、数据类型扩展、指令集增加和精度控制。文中通过C代码示例展示了如何使用AVX进行向量加法。AVX对科学计算、图像处理和机器学习等领域提供了显著的性能提升。编译时需确保编译器支持AVX标志。
|
5月前
|
前端开发 网络协议 Go
为什么ChatGPT选择了SSE,而不是WebSocket?
为什么ChatGPT选择了SSE,而不是WebSocket?
189 2
|
11月前
|
前端开发 Java API
响应式编程:Vert.x官网学习
Vert.x 是一个基于 JVM 的轻量级、高性能响应式工具包,适用于最新的服务端后台、互联网、企业应用架构。Vert.x 基于全异步的事件驱动和非阻塞的 IO 模型,可以使用很少的线程资源处理大量并发请求。Vert.x 还提供了分布式系统、微服务、数据库、消息传输、web开发支持等特性,使得开发者可以轻松编写响应式应用程序,具有很好的扩展性和可靠性。
120 1
|
存储 编解码 网络协议
Opus从入门到精通(五)OggOpus封装器全解析
针对上面的问题我们可以自定义一种封装格式,增加类似于WAV的Header,Header中存储元数据,每一帧音频数据前面增加可以标识帧边界的头,但是又会引出其他问题
1214 0
跟Xilinx SAE 学HLS系列视频讲座笔记(6)—— 函数优化
1. 函数层面的优化 从函数这个角度来说代码风格,主要是看参数的数据类型,C++中的数据类型是以8为边界的,而实际硬件中我们可能会遇到任意精度的数据类型,因此我们一定在C++中定义为任意精度的数据类型;
105 0
跟Xilinx SAE 学HLS系列视频讲座笔记(6)—— 函数优化
跟Xilinx SAE 学HLS系列视频讲座笔记(4)——For循环优化(下)
目录 第一讲 For循环优化的性能指标 第二讲 for循环优化-循环合并 第三讲 for循环优化-数据流 第四讲 嵌套for循环优化 第五讲 for循环优化其他方法
113 0
跟Xilinx SAE 学HLS系列视频讲座笔记(4)——For循环优化(下)
|
存储 调度
跟Xilinx SAE 学HLS系列视频讲座笔记(4)——For循环优化(中)
目录 第一讲 For循环优化的性能指标 第二讲 for循环优化-循环合并 第三讲 for循环优化-数据流 第四讲 嵌套for循环优化 第五讲 for循环优化其他方法
205 0
跟Xilinx SAE 学HLS系列视频讲座笔记(4)——For循环优化(中)