服务器发送事件Server-sent events详解与示例
Server-sent events
服务端进行数据推送除了WebSocket
之外,还可以使用Server-Send-Event
方案。
与 WebSocket
不同的是,服务器发送事件是单向的。数据消息只能从服务端到发送到客户端(如用户的浏览器)。这使其成为不需要从客户端往服务器发送消息的情况下的最佳选择。
Server-Sent-Events
(SSE
)是一种HTML5
API
,用于在服务器和客户端之间实时推送数据流。 SSE
可以用于实现实时通知、实时聊天、实时数据更新和实时监控等功能。
服务器发送事件API包含在EventSource
接口中
EventSource
EventSource
接口是 web 内容与服务器发送事件通信的接口。
一个 EventSource
实例会对HTTP
服务器开启一个持久化的连接,以 text/event-stream
格式发送事件,此连接会一直保持开启直到通过调用EventSource.close()
关闭。
创建一个EventSource实例
创建一个EventSource
对象,开启与服务器的连接并接收事件
const evtSource = new EventSource("ssedemourl")
如果生成事件的代码不同源,需要创建一个新的包含url和options参数的EventSource
对象
const evtSource = new EventSource("//api.example.com/ssedemourl", {withCredentials: true,
})
事件流格式
事件流是一个简单的文本数据流,文本应该使用 UTF-8
格式的编码。事件流中的消息由一对换行符分开。以冒号开头的行为注释行,会被忽略。
每个字段由字段名表示,后面是冒号,然后是该字段值的文本数据。
字段有以下几个
-
event
用于标识事件类型的字符串。如果指定了这个字符串,浏览器会将具有指定事件名称的事件分派给相应的监听器;客户端应该使用
addEventListener()
来监听指定的事件。如果一个消息没有指定事件名称,那么可以调用onmessage
处理程序。 -
data
消息的数据字段。当
EventSource
接收到多个以data:
开头的连续行时,会将它们连接起来,在它们之间插入一个换行符。末尾的换行符会被删除。 -
id
事件 ID,会成为当前
EventSource
对象的内部属性“最后一个事件 ID”的属性值。 -
retry
重新连接的时间。如果与服务器的连接丢失,浏览器将等待指定的时间,然后尝试重新连接。这必须是一个整数,以毫秒为单位指定重新连接的时间。如果指定了一个非整数值,该字段将被忽略。
所有其他的字段名都会被忽略。
示例:
纯数据messagee
data: some text
命名事件
event:usermessage
data: {"username": "bobby", "age": "22"}
混合事件,在一个事件流中同时使用命名事件和未命名事件
data: some textevent:usermessage
data: {"username": "bobby", "age": "22"}
监听open
事件
EventSource
接口的onopen
属性是一个事件处理器,它在收到 open
事件时被调用,在那时,连接刚被打开。
evtSource.onopen = function () {console.log("Connection to server opened.");
}
监听message
事件
如果服务器发送的消息中没有定义event
字段,这些消息则都为message
事件,要接收从服务端发送过来的message
事件,需要为message
事件添加事件处理程序
前端部分代码:
evtSource.onmessage = (event) => {console.log(event.data)
}
// onmessage的等价写法
evtSource.addEventListener('message', (event) => {console.log(event.data)
});
服务端部分示例代码:
stream.write(`data: ${song[index]}\n\n`)
监听event
字段中的自定义事件
如果服务器发送的消息中定义了event
字段,以event
中给定的名称来接收事件
前端部分代码:
evtSource.addEventListener('custom', (e) => {console.log(.data)
})
服务端部分示例代码:
stream.write(`event: custom\ndata: ${song[index]}\n\n`) // 此处定义了event字段,名称为custom
处理错误事件
当发送网络超时或其他问题时,会生成一个错误事件。在事件源连接未能打开时触发
evtSource.onerror = (err) => {console.error("EventSource failed:", err);
}
关闭EventSource
事件
默认情况下,如果客户端和服务器之间的连接关闭,则SSE连接会重新启动,可以在前端的事件上调用close()
方法终止连接。
evtSource.close()
从服务端发送事件示例
发送事件的服务端脚本需要使用text/event-stream
MIME类型响应类型。每个通知以文本块形式发送,并以一对换行符结尾。
Node.js中使用koa2演示SSE连接,服务端示例代码
const router = require('koa-router')()
const { PassThrough } = require('stream')// 测试EventSource
router.get('/eventSource', async (ctx, next) => {try {const stream = new PassThrough()ctx.set({ 'Content-Type':'text/event-stream' })// 将歌词变成一个数组let song = ['我', '懒', '得', '写', '你', '谷', '搜', '到', '处', '皆', '只', '因', '你', '太', '美', '浅', '唱', '动', '人', '说', '不', '出', '我', '试', '着', 'end', ]let index = 0;setInterval(() => {const str = song[index];if (str) {// 方式1:格式是 data: xxx\n\n,事件要一对\n结束// stream.write(`data: ${song[index]}\n\n`)// 方式2,定义了event字段,自定义事件stream.write(`event: custom\ndata: ${song[index]}\n\n`)// 发送的数据为json字符串// stream.write(`event: custom\ndata: {"name": "${song[index]}"}\n\n`)} else {stream.write('0')}index++}, 500)ctx.body = stream} catch (error) {error.status = error.status ? error.status : 500ctx.throw(error.status, error)}
})
客户端接收示例
前端使用的vue3
const getSSE = () => {const source = new EventSource(`http://localhost:8081/api/eventSource`);let str = ''source.onopen = () => console.log("Connected");source.onerror = console.error;// 方式1:监听message事件// source.onmessage = (e) => {// if (e.data === 'end') {// // 判定end,关闭连接// source.close()// }// str += e.data// console.log(str)// }// 方式2,监听自定义custom事件source.addEventListener('custom', (e) => {str += e.data// str += JSON.parse(e.data).name // 接收json字符串console.log(str)})
}
getSSE()
效果演示
现在很火的ChatGPT在回答中的打字效果就是使用了SSE的方式。
相关文章:

服务器发送事件Server-sent events详解与示例
Server-sent events 服务端进行数据推送除了WebSocket之外,还可以使用Server-Send-Event方案。 与 WebSocket不同的是,服务器发送事件是单向的。数据消息只能从服务端到发送到客户端(如用户的浏览器)。这使其成为不需要从客户端…...

SOLIDWORKS 多实体的建模方式
SOLIDWORKS多实体是SOLIDWORKS中一个非常有用的功能。在SOLIDWORKS中,对于模型的设定通常被大家所熟知的有以下几种类型:零件、装配体以及工程图。 其实还有一种划分,就是多实体。严格意义上来说,多实体既不属于零件也不属于装配体…...

NSSCTF web 刷题记录1
文章目录 前言题目[GXYCTF 2019]禁止套娃方法一方法二 [NCTF 2019]Fake XML cookbook[NSSRound#7 Team]ec_RCE[NCTF 2018]Flask PLUS 前言 今天是2023.9.3,大二开学前的最后一天。老实说ctf的功力还是不太够做的题目太少,新学期新气象。不可急于求成&am…...

遥感指数数据库
目前遥感指数多种多样,那怎么针对不同的应用领域选择合适的植被指数?不同卫星又有哪些可以反演的指数? Henrich等人开发了Index Database(网址:https://www.indexdatabase.de/),总结了目前主流的遥感指数,…...

如何让insert程序速度快,可以试试联合SQL(insert 和 select 一起使用)?
查询添加可选择SQL执行,速度远超程序执行 insert 和 select案例 insert into 表1(列1,列2,列3,...) select 列1,列2,列3,...from表2(GROUP BY 列)116511 条数据 耗时45秒, 如果是程序查询然后再insert,则需要30分钟左右!&#x…...

IP地址、网关、网络/主机号、子网掩码关系
一、IP地址 IP地址组成 IP地址分为两个部分:网络号和主机号 (1)网络号:标识网段,保证相互连接的两个网段具有不同的标识。 (2)主机号:标识主机,同一网段内,主机之间具有相同的网…...

使用skvideo.io.vread读取avi视频,报错“No way to determine width or height from video...”
问题描述: 一开始安装sk-video,在使用skvideo.io.vread读取avi视频,报错“No way to determine width or height from video. Need -s in inputdict. Consult documentation on I/O.” 解决方案: 1. 卸载sk-video pip uninsta…...

Nomad 系列-安装
系列文章 Nomad 系列文章 Nomad 简介 开新坑!近期算是把自己的家庭实验室环境初步搞好了,终于可以开始进入正题研究了。 首先开始的是 HashiCorp Nomad 系列,欢迎阅读。 关于 Nomad 的简介,之前在 大规模 IoT 边缘容器集群管…...

网络版五子棋C++实现
目录 1.项目介绍 2.开发环境 3.核心技术 4.环境搭建 5.WebSocketpp介绍 5.1WebSocketpp是什么 5.2为什么使用WebSocketpp 5.3原理解析: 5.4WebSocketpp主要特性 6.WebSocketpp使用 7.JsonCpp使用 8.MySQL API 9.项目模块设计以及流程图 10.封装日志宏…...

项目招标投标公众号小程序开源版开发
项目招标投标公众号小程序开源版开发 以下是一个招标投标公众号小程序的功能列表: 用户注册与登录:用户可以注册账号并登录公众号小程序。项目发布:用户可以发布招标项目的详细信息,包括项目名称、招标单位、项目描述、招标要求…...

华为OD机试-机器人走迷宫
题目描述 机器人走一个迷宫,给出迷宫的x和y(x*y的迷宫)并且迷宫中有障碍物,输入k表示障碍物有k个,并且会将障碍物的坐标挨个输入. 机器人从0,0的位置走到x,y的位置并且只能向x,y增加的方向走,不能回退. 如代码类注释展示的样子,#表示可以走的方格,0代表障碍,机器人从0,0的位置…...

Jenkins搭建步骤Linux环境
1、进入目标目录开始准备环境 安装jdk 安装maven 安装tomcat 安装node 下载Jenkins.war并且拷贝进tomcat的webapp的文件夹下。 环境变量配置如下自行更改: #--------------For JDK---------------- export JAVA_HOME/usr/local/java/jdk1.8.0_192 export PATH/usr…...

2023 AZ900备考
文章目录 如何学习最近准备考AZ900考试,找了一圈文档,结果发现看那么多文档,不如直接看官方的教程https://learn.microsoft.com/zh-cn/certifications/exams/az-900/ ,简单直接,突然想到纳瓦尔宝典中提到多花时间进行思…...

青翼科技基于VITA57.1的16路数据收发处理平台产品手册
FMC211是一款基于VITA57.1标准规范的实现16路LVDS数据采集、1路光纤数据收发处理FMC子卡模块。 该板卡支持2路CVBS(复合视频)视频输入,能够自动检测标准的模拟基带电视信号,并将其转变为8位ITU-R.656接口信号或者4:2:2分量视频信…...

Ansible_自动化运维实战(一)
1.DELL的一款服务器的价格、型号、配置(CPU,内存、硬盘、支持的RAID功能) DELL 服务器的定价、型号和配置因型号而异,可以通过访问 DELL 官方网站或联系 DELL 客户服务获取具体信息。一种示例是 DELL PowerEdge R740,其…...

说说Flink中的State
分析&回答 基本类型划分 在Flink中,按照基本类型,对State做了以下两类的划分: Keyed State,和Key有关的状态类型,它只能被基于KeyedStream之上的操作,方法所使用。我们可以从逻辑上理解这种状态是一…...

适合心理法律在线咨询预约含视频图文电话咨询功能的小程序开发
目前智能手机普及,很多以前需要线下咨询的场景都被搬到了线上,这样既可以使咨询者更方便,也可以使被咨询者接待效率更高,服务更多咨询者。基于此我们开发了专门的一款具有线上咨询功能的小程序,同时为了方便被咨询者服…...

Redis-Cluster集群操作--添加节点、删除节点
一、环境部署 部署好Redis-Cluster集群,参考上个本人的博客:Redis-Cluster集群的部署(详细步骤)_是胡也是福的博客-CSDN博客 新准备一台机器,修改主机名,关闭防火墙和selinux,参考:…...

ModaHub魔搭社区:星环科技向量数据库Hippo社区版来啦
大语言模型正在与企业应用迅速结合,并深刻改变企业的各个产业环节。而大模型训练所使用的数据包含了如文档、图片、音视频等各种类型的非结构化数据,传统关系型数据库能力有限。通过将这些非结构化数据转换为多维向量,可以结构化地在向量数据库中进行管理,实现高效的数据存…...

gitHub添加ssh
gitHub添加ssh 首先你需要有一个github的账户 第一步: 打开终端,输入以下命令,注意“your email”处你自己的邮箱,创建新的ssh ssh-keygen -t ed25519 -C “your email” 第二步:使用ssh登录ssh-agent,终端…...

sql:SQL优化知识点记录(十)
(1)慢查询日志 Group by的优化跟Order by趋同,只是多了一个having 开启慢查询日志: 演示一下慢sql:4秒之后才会出结果 查看一下:下方显示慢查询的sql (2)批量插入数据脚本 函数和存…...

STM32 RTC实验
RTC时钟简介 STM32F103的实时时钟(RTC)是一个独立的定时器。 STM32的RTC模块拥有一组连续计数的计数器,在相对应的软件配置下,可提供时钟日历的功能。 修改计数器的值可以重新设置系统的当前时间和日期。 RTC模块和时钟配置系统…...

C#设计打开文件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System...

mysql指令行登录如何添加mysql.sock的配置?(亲测)
在 MySQL 的命令行登录中,你可以使用 --socket 参数来指定 MySQL 的 Unix 套接字文件(mysql.sock)的位置。以下是使用 --socket 参数进行 MySQL 命令行登录的示例: mysql --socket/path/to/mysql.sock -u username -p 将 /path…...

Git 设置和清除用户名和邮箱
作为一款十分流行的版本控制工具,Git 得到了越来越多的开发者的喜爱。然而,当使用 Git 上传代码的时候,很多开发者都会遇到一个问题,那就是如果在提交代码时错误地设置了用户名和邮箱,那么这些信息就会被永久地记录在 …...

【系统设计系列】 回顾可扩展性
系统设计系列初衷 System Design Primer: 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版: https://github.com/donnemart…...

科兴未来 |轨道交通专业赛 第十二届中国创新创业大赛
一、大赛主题 产业赋能 创享未来 二、参赛方向 1.自主可控的关键核心技术。面向“一带一路”国际市场、国内区域/市域轨道交通一体化需求,征集不同轨制、供电制式、通信信号、交通方式、载运工具等跨标准体系的适配关键应用技术,包括但不限于:列车自动…...

leetcode 42. 接雨水
2023.8.29 本题可以用双指针做,求出每一列能盛的雨水,再相加即可。不过暴力法会超时,需要优化。 双指针(暴力): class Solution { public:int trap(vector<int>& height) {int ans 0;for(int …...

【Lychee图床】本地电脑搭建私人图床,公网远程访问
文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站,可以看做是云存储的一部分,既可…...

【MySQL系列】-ORDER BY……HAVING详解及limit
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...