服务端推送、 server sent event、sse、springboot+sse

news2024/11/15 3:54:27

SSE(server-sent events)

SSE全称server-sent events,翻译过来是服务端发送事件,通常的http请求,客户端请求,服务端返回响应,一次只能返回一个值;SSE使用的http协议,客户端请求后,服务端可以多次返回响应,返回的http Content-Type:text/event-stream,客户端请求后,仍然保持http链接不关闭,服务端可多次发送响应,客户端监听事件,获取响应,这适用新闻实时更新、股票实时更新等服务端推送到客户端的场景。在chatgpt中提问问题后,答案不是一下子出来的,而是断断续续出来的,就是用的SSE技术。
在这里插入图片描述

SSE与websocket的异同

SSEwebsocket
基于http协议的基于websocket协议
单向的,只能服务端---->客户端双向的,服务端<------>客户端
消息有id、event、data、retry等字段不限格式
  • 普通http请求
    在这里插入图片描述
  • SSE
    在这里插入图片描述

实践

SSE通信分为客户端(通常是浏览器端)和服务端,客户端用来发送请求,监听事件,关闭链接等。服务端,就是普通的http服务,区别就是Content-Type:text/event-stream

客户端

客户端使用EventSource API来实现通信,

  • 创建EventSource实例
const evtSource = new EventSource("ssedemo.php");

如果是跨域,则

const evtSource = new EventSource("//api.example.com/ssedemo.php", {
  withCredentials: true,
});
  • 监听服务端推送的消息
evtSource.onmessage = (event) => {
  const newElement = document.createElement("li");
  const eventList = document.getElementById("list");

  newElement.textContent = `message: ${event.data}`;
  eventList.appendChild(newElement);
};
  • 监听自定义的事件,使用addEventListener方法,监听事件为ping的
evtSource.addEventListener("ping", (event) => {
  const newElement = document.createElement("li");
  const eventList = document.getElementById("list");
  const time = JSON.parse(event.data).time;
  newElement.textContent = `ping at ${time}`;
  eventList.appendChild(newElement);
});
  • 监听错误
evtSource.onerror = (err) => {
  console.error("EventSource failed:", err);
};
  • 关闭,注意,关闭只能从客户端发起。
evtSource.close();

服务端

服务端跟正常的http 服务差不多,除了响应类型是text/event-stream

  • Event Stream格式
    event: 事件名称,如果不写事件名,则被客户端的onMessage监听;有事件名,则被对应的addEventListener监听。
    data: 消息的数据字段
    id: 事件的id
    retry: 断线重连的等待时间,单位毫秒

  • 只发数据

//冒号开头的是注释,可用于心跳
: this is a test stream

data: some text

data: another message
data: with two lines
  • 命名事件
event: userconnect
data: {"username": "bobby", "time": "02:33:48"}

event: usermessage
data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}

event: userdisconnect
data: {"username": "bobby", "time": "02:34:23"}

event: usermessage
data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}

也可以一会发数据消息、一会发命名事件消息

springboot支持SSE

在spring framework文档中,springmvc中ResponseBodyEmitter 、SseEmitter (ResponseBodyEmitter的子类)归属为异步请求(适用异步返回请求值),异步请求细分为Http Streaming(适用返回多个值的情况)

  • java端代码

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@RestController
@RequestMapping("question")
public class AskQuestionController {



    @GetMapping(value = "/askQuestion", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter askQuestion() {
        final SseEmitter sseEmitter = new SseEmitter();
        final ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() -> {
            for (int i = 0; i < 100; i++) {
                String data = getCurDateStr();
                try {
                    sseEmitter.send(SseEmitter.event().id(String.valueOf(i+1)).data(data).name("custom_event_name"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        return sseEmitter;

    }

    private static String getCurDateStr() {
        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        return simpleDateFormat.format(new Date());
    }
}

  • 客户端代码
<button onclick="startSSE()">开始</button>
<button onclick="closeSSE()">关闭</button>
内容是:
<ul id="list">

</ul>
<script type="text/javascript">
    let evtSource;

    function startSSE() {
        evtSource = new EventSource("/question/askQuestion");
        evtSource.addEventListener("custom_event_name", (event) => {
            const newElement = document.createElement("li");
            const eventList = document.getElementById("list");
            newElement.textContent = `收到的数据: ${event.data}`;
            eventList.appendChild(newElement);
        });
    }

    function closeSSE() {
        evtSource.close()
    }
</script>
  • 效果,用了原生EventSource在dev tools的EventStream中显示事件数据
    在这里插入图片描述

  • 客户端自动重连
    在这里插入图片描述

问题

  • 在chrome devtools中的EventStream中看不到数据
    • 这是因为devtools只支持原生的EventSource,不支持EventSource Polyfill
    • Event does not show up in the Chrome EventStream subtab inside the Network tab when viewing the eventstream connection
    • why did not found the chatgpt event stream data in google chrome devtools
    • 在这里插入图片描述
  • EventSource API不支持POST方法,只能GET,但可以不使用EventSource API,用sse.js来实现SSE POST
var source = new SSE("get_message.php", {payload: 'Hello World'});

总结

SSE是一种规范而不是一种新协议,它使用http通信,返回的Content-Type:text/event-stream,客户端通过监听事件不断获取数据,链接断掉后会自动重连,接收完数据后由客户端发起关闭连接。

参考

  • Using server-sent events

  • Can Server Sent Events (SSE) with EventSource pass parameter by POST

  • How to pass POST parameters with HTML SSE?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bbr 的 “最优操作点”

最近做一组测试&#xff0c;我复现了一组结果准备阐释另一个事。先看这个测试结果&#xff1a; 常规的一个 wrk2(expected_latency_timing 改为 actual_latency_timing 计数) 压 nginx 的测试&#xff0c;调整 -R 参数&#xff0c;Req/sec 同步增加&#xff0c;当 Req/sec 不…

(免费领源码) Asp.Net#SQL Server校园在线投票系统10557-计算机毕业设计项目选题推荐

摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。由于现在网络的发达&#xff0c;校园投票通过网…

液氮恒温器主要特点

恒温器是直接或间接控制一个或多个热源和冷源来维持所要求的温度的一种装置。 主要特点 更宽温区&#xff1a;液氮恒温器的温区宽度扩展到了80K~500K&#xff0c;为液氮温区实验用户提供更宽温区解决方案。 操作更简单&#xff1a;液氮恒温器在样品更换、液氮填充、控制液氮…

UI自动化概念 + Web自动化测试框架介绍

1.UI自动化测试概念:我们先明确什么是UI UI&#xff0c;即(User Interface简称UI用户界面)是系统和用户之间进行交互和信息交换的媒介 UI自动化测试: Web自动化测试和移动自动化测试都属于UI自动化测试&#xff0c;UI自动化测试就是借助自动化工具对程序UI层进行自动化的测试 …

【分享】RAR压缩包的密码可以取消吗?

在日常工作中&#xff0c;我们可能经常用到RAR文件&#xff0c;RAR作为一种常见的压缩文件格式&#xff0c;可以将一个或多个文件压缩成单个文件&#xff0c;方便传输和保存。 RAR文件还可以设置“打开密码”&#xff0c;这样只有输入正确的密码才能打开压缩包里面的文件&…

SpringBoot 快速实现 api 加密

在项目中&#xff0c;为了保证数据的安全&#xff0c;我们常常会对传递的数据进行加密。常用的加密算法包括对称加密&#xff08;AES&#xff09;和非对称加密&#xff08;RSA&#xff09;&#xff0c;博主选取码云上最简单的API加密项目进行下面的讲解。 下面请出我们的最亮的…

5 个编写高效 Makefile 文件的最佳实践

在软件开发过程中&#xff0c;Makefile是一个非常重要的工具&#xff0c;它可以帮助我们自动化构建、编译、测试和部署。然而&#xff0c;编写高效的Makefile文件并不是一件容易的事情。在本文中&#xff0c;我们将讨论如何编写高效的Makefile文件&#xff0c;以提高我们的开发…

【Bug——VMware Workstation】虚拟机桥接网络没有 VMnet0

此时 没有VMnet0用来桥接网络。 接下来进行解决 1.找到安装VM的路径&#xff0c;在安装的目录里面找到如图所示的三个文件&#xff1a; 2.依次点击鼠标右键 将这三个文件依次安装如图所示&#xff1a; 二.windows下的操作 1.首先 找到电脑的控制面板->网络和internet->…

二维码智慧门牌管理系统升级解决方案:采集计划精细化管理的艺术

文章目录 前言一、采集计划的定义和配置流程二、多采集计划配置策略三、采集计划的实践应用 前言 在数字化时代&#xff0c;建设智慧城市需要借助各种先进的技术工具。其中&#xff0c;二维码智慧门牌管理系统在城市管理、资源调配和公众服务等方面扮演着举足轻重的角色。关键…

不容错过的Spring框架解析,掌握开发中的关键技术

Spring 原理 它是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 Spring 特点 轻量级 控制反转 面向切面 容器 框架集合 Spring特征 Spring 核心组件 Spring 常用模块 Spring 主要包 Spring …

Self-Supervised MultiModal Versatile Networks

方法 视觉-音频空间S v a _{va} va​&#xff0c;嵌入z v , v a t _{v,vat} v,vat​ 体会 一篇文章只有一张图&#xff0c;笑死人。作者且未回复问题

体育竞技分析

体育竞技分析是一项重要的工作&#xff0c;它通过对运动员的数据进行收集、处理和分析&#xff0c;可以帮助教练和球队做出更明智的决策。Python作为一种强大的编程语言&#xff0c;提供了丰富的库和工具&#xff0c;可以用于体育竞技数据的分析和可视化。本文将介绍如何使用Py…

二、BurpSuite Decoder解码器

一、编码解码 解释&#xff1a;BurpSuite 可以用这个模块来轻松进行编码解码&#xff0c;下面是支持的类型 URL HTML Base64 ASCIIhex Hex Octal Binary Gzip 注意&#xff1a;特别注意的是URL编码&#xff0c;一般的在线网站都无法对比如‘abc’的文本编码&#xff0c;burps…

【0基础学Java第二课】数据类型与变量

2. 数据类型与变量 2.1 字面常量2.2 数据类型2.3 变量2.3.1 变量概念2.3.2 语法格式 2.4 整型变量2.4.1 整型变量2.4.2 长整型变量2.4.3 短整型变量2.4.4 字节型变量 2.5 浮点型变量2.6 字符型2.7 布尔型变量2.8 类型转换2.9 类型提升2.10 字符串类型2.10.1 字符串拼接操作符 2…

linux中nginx配置https

一、版本适配 版本一定要适配&#xff0c;否则会报错各种参数定位不到不识别的错误&#xff0c;以下是版本适配信息&#xff0c;各位观客自行按照以下信息匹配版本。 Nginx 1.11.5及以上版本与OpenSSL 1.0.2及以上版本兼容。Nginx 1.15.2及以上版本与OpenSSL 1.1.1及以上版本兼…

足底筋膜炎多久能好

足底筋膜炎4-6周左右能好。 足底筋膜炎一般经过系统治疗后&#xff0c;如外敷‘古顺敷堂’筋膜贴在3-5天的时间水肿明显的减轻&#xff0c;度过水肿期之后&#xff0c;疼痛的症状能够得到明显的缓解&#xff0c;但是如果进行下床活动以及剧烈的运动、受凉&#xff0c;还可能会…

虚拟技术和容器技术的对比

1.概念 容器技术是一种内核轻量级的操作系统层虚拟化技术&#xff0c;能隔离进程和资源。 虚拟机&#xff08;VM&#xff09;技术是一种创建于物理硬件系统&#xff0c;充当虚拟计算机系统的虚拟环境&#xff0c;该虚拟机可以独 立运行在一个完全隔离的环境中&#xff0c;向本…

CrossOver软件2023官方破解版本下载

CrossOver软件的核心是Wine&#xff0c;它为用户提供了一个友好的图形界面&#xff0c;而且持续对受支持的Windows应用程序进行测试&#xff0c;从而使用户可以专注于应用程序的使用上&#xff0c;不必为安装使用Windows应用程序花费大量的时间去配置Wine、去调试应用软件的兼容…

Modality to Modality Translation

模型架构 信息向量记为V 作者未提供可直接运行的代码

JVM面试知识点整理

文章目录 (一) JVM组成JVM组成部分和运行流程从图中可以看出 JVM 的主要组成部分运行流程&#xff1a;程序计数器Java堆虚拟机栈方法区堆栈的区别是什么&#xff1f; (二) 类加载器双亲委派模型类装载的执行过程 (三) 垃圾回收对象什么时候可以被垃圾回收哪些可以作为根对象 垃…