[Net]SSE消息推送简介

news/2024/11/22 20:42:32/

文章目录

    • SSE网络协议
      • 客户端
      • 服务端
      • 事件
    • SSE示例
      • 客户端
      • 服务端

SSE(Server-Sent Events)是一种服务端到客户端(浏览器)的单向消息推送方式。

SSE网络协议

SSE是基于HTTP协议的,客户端向服务端发起一个请求,建立长连接( keep-alive connection);服务端向客户端发送(应答)不是一次性的包,而是一个数据流。

SSE

客户端

要实现SSE协议,客户端发起的请求头中需要携带:

  • Accept: text/event-stream: 表示可接收事件流类型
  • Cache-Control: no-cache: 禁用任何的事件缓存
  • Connection: keep-alive: 表示正在使用持久连接

如:

GET /sse HTTP/1.1 Accept: text/event-stream Cache-Control: no-cache Connection: keep-alive

SSE默认支持断线重连机制,在连接断开时会触发EventSource的error事件,同时自动重连。

服务端

服务端应答头中需要包含:

  • Content-Type: text/event-stream;charset=UTF-8: 表示标准要求的事件的媒体类型和编码
  • Transfer-Encoding: chunked: 表示服务器流式传输动态生成的内容,因此内容大小事先未知

如:

HTTP/1.1 200 Content-Type: text/event-stream;charset=UTF-8 Transfer-Encoding: chunked

事件

事件采用UTF-8编码的文本消息:

  • 事件之间由两个换行符\n\n分隔;
  • 每个事件由一个或多个{key}: {value}字段组成;字段间由单个换行符\n分隔。
  • 若某行以冒号:开始,客户端应忽略:可用于防止中间代理因超时关闭连接;如:ping

规范中定义了事件的四种字段:

  • retry:表示超时重连间隔(毫秒);
  • data:表示包含的是数据,可多次出现;
  • event:表示事件的类型(若不写,默认为message),浏览器会生成对应类型的事件;
  • id:表示事件标识符;
id: 1
event: chat
retry: 3000
data: firstid: 2
event: chat
retry: 3000
data: second
data: second continue

注意:如果服务器端返回的数据中包含了事件的标识符id,浏览器会记录最近一次接收到的事件的标识符。当浏览器因断开重连时,会通过HTTP头Last-Event-ID来声明最后一次接收到的事件的标识符;服务器端可根据此标识符确定从哪个事件开始来继续连接。

SSE示例

客户端

客户端SSE是在EventSource中实现的,EventSource内置了3个EventHandler属性、2个只读属性和1个方法:

  • onopen属性:在连接打开时被调用。
  • onmessage属性:在收到一个没有event属性的消息时被调用。
  • onerror属性:在连接异常时被调用。
  • readyState只读属性:代表连接状态;可能值是CONNECTING(0),OPEN(1),CLOSED(2)
  • url只读属性:连接的URL。
  • close()方法:关闭连接
'use strict';if (window.EventSource) {// 创建 EventSource 对象连接服务器const source = new EventSource('http://localhost:2000/stream');// 连接成功后会触发 open 事件source.addEventListener('open', () => {console.log('Connected');}, false);// 服务器发送信息到客户端时,如果没有 event 字段,默认会触发 message 事件source.addEventListener('message', e => {console.log(`data: ${e.data}`);}, false);// 自定义 EventHandler,在收到 event 字段为 slide 的消息时触发source.addEventListener('slide', e => {console.log(`data: ${e.data}`); // => data: 7}, false);// 连接异常时会触发 error 事件并自动重连source.addEventListener('error', e => {if (e.target.readyState === EventSource.CLOSED) {console.log('Disconnected');} else if (e.target.readyState === EventSource.CONNECTING) {console.log('Connecting...');}}, false);
} else {console.error('Your browser doesn\'t support SSE');
}

服务端

服务端使用基于Flask的实现

from flask import Flask, request
from flask import Response
from flask import render_templateapp = Flask(__name__)def get_message():"""this could be any function that blocks until data is ready"""time.sleep(1)s = time.ctime(time.time())return json.dumps(['当前时间:' + s , 'a'], ensure_ascii=False)@app.route('/')
def hello_world():return render_template('index.html')@app.route('/stream')
def stream():user_id = request.args.get('user_id')print(user_id)def eventStream():id = 0for i in range(10):id +=1# wait for source data to be available, then push ityield 'id: {}\nevent: add\ndata: {}\n\n'.format(id,get_message())id +=1yield 'id: {}\nevent: done\n\n'.format(id)    return Response(eventStream(), mimetype="text/event-stream")if __name__ == '__main__':app.run(port=2000)

http://www.ppmy.cn/news/51379.html

相关文章

命令行find查找删除指定文件夹下内容方法

删除一个文件夹下的2天以前的内容 可以使用 find 命令结合 -mtime 参数来删除一个文件夹下指定时间之前的内容。具体命令如下: find /path/to/folder -type f -mtime 1 -delete解释一下各参数的含义: /path/to/folder:需要删除内容的文件夹…

【Linux】System V 共享内存、消息队列、信号量

🍎作者:阿润菜菜 📖专栏:Linux系统编程 system V共享内存介绍 System V 共享内存是一种进程间通信的机制,它允许多个进程共享一块物理内存区域(称为“段”)。System V 共享内存的优点是效率高&…

微搭低代码学习之数据展示

低代码平台是一个快速发展的领域,未来有着广阔的发展前景。以下是一些低代码平台未来的发展方向: 1.人工智能和机器学习 随着人工智能和机器学习技术的不断发展,低代码平台将能够更好地利用这些技术来提高应用程序的智能化和自动化水平。例如…

演示视频:Jira企业微信插件邀您一起迈入移动办公时代,高效处理Jira Issue

在当今快节奏的商务环境中,移动端办公已经成为现代企业管理和团队协作的不可忽视的趋势。现代职场注重灵活性、高效性和便捷性,员工在手机或平板上处理工作事务已经成为日常工作的一部分。 为了满足这一需求,龙智自主研发了一款无缝集成企业微…

浙大数据结构第二周之线性结构

题目详情: 02-线性结构1 两个有序链表序列的合并 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。 函数接口定义: List Merge( List L1, List L2 );其中List结构定义如下: typedef struct N…

约瑟夫环的三种解法(循环链表、数组和用数组模拟链表)

目录 前言 一、用循环链表实现 二、用数组实现 三、用数组模拟链表实现 前言 题目描述: 编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。 下一个人继续从 1 开始报数。 n-1 轮结束以后,只剩下一个人&am…

线程同步方式之一互斥锁

线程同步的4种方式:互斥锁、条件变量、读写锁、信号量 了解概念-临界资源、互斥、临界区、原子性 回想一下在信号量那部分提起过的几个概念,将多个执行流串行安全访问的共享资源称为临界资源,多个执行流中访问临界资源的代码所在的地址空间…

五一假期出游攻略【诗与远方】

原文在:PUSDN 可以导入作为模板引用。 五一旅行计划 假期倒计时 [该类型的内容暂不支持下载] 本次目标:五一旅行计划【画饼版】 前言 任何一个地方,一个城市,都有可观赏的地方,如果没去过邢台的,建议五一去…