[Net]SSE消息推送简介

2023-05-16

文章目录

    • 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: first

id: 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_template

app = 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 = 0
        for i in range(10):
            id +=1
            # wait for source data to be available, then push it

            yield 'id: {}\nevent: add\ndata: {}\n\n'.format(id,get_message())

        id +=1
        yield 'id: {}\nevent: done\n\n'.format(id)    


    return Response(eventStream(), mimetype="text/event-stream")


if __name__ == '__main__':
    app.run(port=2000)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[Net]SSE消息推送简介 的相关文章

  • 将绝对路径转换为相对路径 C# [重复]

    这个问题在这里已经有答案了 可能的重复 获取相对于当前工作目录的路径 https stackoverflow com questions 703281 getting path relative to the current working
  • 如何在 .NET 中轻松取消转义 XML 实体

    我有一些代码返回 XMLNode 的 InnerXML 该节点可以只包含一些文本 带有 HTML 或 XML 例如
  • 使用 .NET 在 Windows 中创建弹出式“烤面包机”通知

    我正在使用 NET 并创建一个桌面应用程序 服务 当触发某些事件时 它将在桌面的一角显示通知 我不想使用常规的消息框 b c 那样会造成太大的干扰 我希望通知滑入视图 然后在几秒钟后淡出 我正在考虑一种类似于 Outlook 收到新邮件时发
  • 实体框架左外连接和分组抛出:ORA-00907:缺少右括号

    我在基于实体框架的数据访问中使用实体框架来定位多个数据库 我们是一个使用 Entity Framework 已有 2 年的团队 生成的代码与 sql server 2008 完美配合 现在 我们在将数据库迁移到 Oracle 11 Expr
  • 如何使用鼠标拖动和移动winform

    我知道如何通过添加以下代码来 拖动和移动 winform Protected Overrides Sub WndProc ByRef m As Message If m Msg 163 And ClientRectangle Contain
  • NET/COM 互操作的 ref string[] 内存泄漏

    我最近发现一个非常奇怪的 对我来说 内存泄漏IEnumString http msdn microsoft com en us library ms693735 28VS 85 29 aspxC 使用的 COM 对象 具体来说 使用已包含先
  • .net MVC 将 MP4 流式传输到 iDevice 问题

    我一直在编写用于提供视频服务的一段代码 但遇到了一些问题 代码如下 public ResumingFileStreamResult GetMP4Video string videoID if User Identity IsAuthenti
  • C# 创建函数队列

    我写了一个名为 QueueManager 的类 class QueueManager Queue functionsQueue public bool IsEmpty get if functionsQueue Count 0 return
  • 用户控件内所有控件均为空

    我有一个 UserControl 它使用 UserControl 以及其他控件 In the ascx文件我有以下代码
  • 如何添加重试以调用 Web 服务?

    我有一个应用程序调用使用 wsHttpBinding 的 Web 服务 我需要在连接超时等情况下对 Web 服务调用实现某种重试功能 执行此操作的最佳方法是什么 我已经阅读过有关 WS ReliableMessaging 的内容 但这不是
  • 如何访问窗口?

    我正在尝试使用其句柄访问特定窗口 即System IntPtr value Getting the process of Visual Studio program var process Process GetProcessesByNam
  • 为什么使用 HTTP 动词?

    因为动词的目标是像 server domain getallrecords 或 server domain delete1record 或类似的 URL 而getallrecords delete1record都是专门为特定目的而设计的 为
  • System.IO.Compression 和 ZipFile - 提取并覆盖

    我使用标准 VB NET 库来提取和压缩文件 它也可以工作 但是当我必须提取并且文件已经存在时 问题就出现了 我使用的代码 Imports Imports System IO Compression 崩溃时我调用的方法 ZipFile Ex
  • 检查Web服务是否存在

    有人可以告诉我确定给定 URL 是否存在 Web 服务 ASP NET 的最佳方法吗 我假设一种方法类似于使用 System Net Webclient 发出请求 但我如何确定它是否是有效的 Web 服务以及我应该发出哪种类型的请求 编辑
  • 如何在没有 WebBrowser 控件的情况下“呈现”HTML

    首先 我不知道 渲染 是否是正确的词 我喜欢从网站获取信息 因此 目前我使用 WebBbrowser 控件 现在我喜欢使用 HttpWebRequests 因为我认为这样更快 并且可以更轻松地使用线程 但我无法使用它们 因为我从 HttpW
  • 如何使用 Serilog ForContext

    我是 Serilog 新手 很难弄清楚如何使用上下文功能 当我运行下面的代码时 输 出文件不包含报告 ID 我缺少什么想法吗 var logger new LoggerConfiguration WriteTo File C Log txt
  • 登录方式使用GINA定制

    我知道在 GINA 中找到大师并不容易 但我的问题最接近进程间通信 IPC 我用非托管 c 编写了我的自定义 GINA 我在其中包含了一个方法来检查用户尝试的指纹的有效性为了登录 该函数将调用正在运行的系统Windows服务中用C 编写的一
  • List.Clear() 在 C# 中是如何实现的?

    我假设它使用数组来实现 List 怎么List Clear 实施的 它实际上清理了数组还是只是为此列表创建了一个新数组 public class List private Array array public void Clear1 arr
  • wait task.delay 有助于加快 UI 刷新速度,但是如何实现呢?

    我有一个视图模型 它正在获取一行记录并显示在 Windows Phone UI 上 这个获取数据的视图模型方法正在执行大量任务 所有任务都标记为等待操作 如下所示 async Task GetData var dataCollection
  • 如何将动态数据写入 MVC 3 Razor 中的页面布局?

    我有带有 Razor 引擎的 MVC 3 C 项目 将动态数据写入 Layout cshtml 的方法和最佳实践是什么 例如 也许我想在网站的右上角显示用户名 该名称来自会话 数据库或基于用户登录的任何内容 更新 我也在寻找将某些数据渲染到

随机推荐

  • PowerShell install Docker+docker-compoer

    docker 前言 Docker 是一个开源的应用容器引擎 xff0c 让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中 xff0c 然后发布到任何流行的 Linux或Windows 机器上 xff0c 也可以实现虚拟化 容器是完全
  • PoweShell Win_server install wsl

    什么是 WSL 2 WSL 2 是适用于 Linux 的 Windows 子系统体系结构的一个新版本 xff0c 它支持适用于 Linux 的 Windows 子系统在 Windows 上运行 ELF64 Linux 二进制文件 它的主要目
  • PoweShell Win_desktop install wsl

    什么是 WSL 2 WSL 2 是适用于 Linux 的 Windows 子系统体系结构的一个新版本 xff0c 它支持适用于 Linux 的 Windows 子系统在 Windows 上运行 ELF64 Linux 二进制文件 它的主要目
  • Linux Shell 实现一键部署二进制go+caddy+filebrowser

    filebrowser filebrowser 是一个使用go语言编写的软件 xff0c 功能是可以通过浏览器对服务器上的文件进行管理 可以是修改文件 xff0c 或者是添加删除文件 xff0c 甚至可以分享文件 xff0c 是一个很棒的文
  • PowerShell install go+caddy+filebrowser+nssm 实现部署文件系统

    filebrowser filebrowser 是一个使用go语言编写的软件 xff0c 功能是可以通过浏览器对服务器上的文件进行管理 可以是修改文件 xff0c 或者是添加删除文件 xff0c 甚至可以分享文件 xff0c 是一个很棒的文
  • Linux Shell 实现一键部署http+用户名密码登录

    Apache 前言 Apache 音译为阿帕奇 是世界使用排名第一的Web服务器软件 它可以运行在几乎所有广泛使用的计算机平台上 xff0c 由于其跨平台和安全性被广泛使用 xff0c 是最流行的Web服务器端软件之一 它快速 可靠并且可通
  • PowerShell install 一键部署http+用户名密码登录实现文件系统

    Apache 前言 Apache 音译为阿帕奇 是世界使用排名第一的Web服务器软件 它可以运行在几乎所有广泛使用的计算机平台上 xff0c 由于其跨平台和安全性被广泛使用 xff0c 是最流行的Web服务器端软件之一 它快速 可靠并且可通
  • [python]异常处理与try语句

    文章目录 异常处理try语句异常信息抛出异常 异常类型自定义异常预定义异常 使用 try except else 来捕获异常 xff0c 且要求异常必须继承自Exception类 异常处理 运行期检测到错误称为异常 try语句 python
  • 大杂烩·OSI和TCP/IP协议与ZigBee技术·一

    1 ZigBee技术 ZigBee是基于IEEE802 15 4标准的低功耗局域网协议 根据国际标准规定 xff0c ZigBee技术是一种短距离 低功耗的无线通信技术 这一名称 xff08 又称紫蜂协议 xff09 来源于蜜蜂的八字舞 x
  • Linux Shell 实现一键部署subversion

    subversion SVN是subversion的缩写 xff0c 是一个开放源代码的版本控制系统 xff0c 通过采用分支管理系统的高效管理 xff0c 简而言之就是用于多个人共同开发同一个项目 xff0c 实现共享资源 xff0c 实
  • PowerShell install 一键部署TortoiseSVN

    TortoiseSVN TortoiseSVN是 Subversion 版本控制系统的一个免费开源客户端 xff0c 可以超越时间的管理文件和目录 文件保存在中央版本库 xff0c 除了能记住文件和目录的每次修改以外 xff0c 版本库非常
  • PowerShell install 一键部署subversion

    subversion SVN是subversion的缩写 xff0c 是一个开放源代码的版本控制系统 xff0c 通过采用分支管理系统的高效管理 xff0c 简而言之就是用于多个人共同开发同一个项目 xff0c 实现共享资源 xff0c 实
  • ROS(1)安装

    1 ros安装 安装过程参考https www cnblogs com letisl p 11815191 html安装wsl略 xff0c 利用mobaxterm进行连接与可视化 1 1 添加源 sudo sh c 39 etc lsb
  • ROS(11)move_base详解

    11 move base详解 11 1 move base配置参数解读 参考链接 xff1a https blog csdn net banzhuan133 article details 90239252 https wenku baid
  • vscode c/c++ global插件实现代码跳转

    问题 在打开某些大的工程 xff0c 如ROS时 xff0c 有些类成员或接口无法进行自动跳转 xff0c 比较难受 vscode插件安装 安装C C 43 43 GNU Global插件 安装C 43 43 Intellsense插件 G
  • gammaray剖析QT程序——如何解析qt版本不同的exe

    gammaray是个非常牛逼的工具 xff0c 但是当我们要分析的exe和当前编译gammaray不一致时 xff0c 是没法使用的 方法很简单 xff0c 其实版本和exe无关 xff0c 和exe依赖的qt dll库有关 xff0c 我
  • do{}while(0)用法

    linux内核和其他一些开源的代码中 xff0c 经常会遇到这样的代码 xff1a do while 0 这样的代码一看就不是一个循环 xff0c do while表面上在这里一点意义都没有 xff0c 那么为什么要这么用呢 xff1f 实
  • windows下vscode安装go插件

    1 GIT安装 vscode安装 略 2 GO在win下安装及环境变量配置 安装完GO后 xff0c 创建一个目录作为工作区 xff0c 如G my project go xff0c 环境变量添加GOPATH并指向该目录 在该目录下创建三个
  • GDB调试中 如何在so共享库中打断点、保存断点以及加载断点

    最近在使用gdb的过程中 xff0c 需要对so文件进行调试 xff0c 在这里记录一下调试中的问题及解决方法 如何在so源文件中打断点 xff1f 首先编译so时需要 g指令 在gdb xxx指令后 xff0c 发现无法在so对应的源码文
  • [Net]SSE消息推送简介

    文章目录 SSE网络协议客户端服务端事件 SSE示例客户端服务端 SSE xff08 Server Sent Events xff09 是一种服务端到客户端 xff08 浏览器 xff09 的单向消息推送方式 SSE网络协议 SSE是基于H