SSE介绍(实现流式响应)

写在前面

本文一起来看下SSE相关内容。

1:SSE是什么

全称,server-send events,基于http协议,一次http请求,server端可以分批推送数据, 不同于websocket的全双工通信,SSM单向通信,一般应用于需要返回的内容较多场景中,比如大模型问答场景,答案可能比较长,就可以使用SSM来实现流式的响应。

2:例子

  • pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>sse-test</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.0</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId>
<!--            <version>4.10.0</version>--><version>3.14.9</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp-sse</artifactId>
<!--            <version>4.10.0</version>--><version>3.14.9</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies></project>
  • SSM server
@RestController
@RequestMapping("/sse")
public class SseController {@RequestMapping("/emitter")public SseEmitter sse(@RequestBody String inputParameter, HttpServletResponse response) {response.setContentType("text/event-stream");response.setCharacterEncoding("UTF-8");SseEmitter emitter = new SseEmitter();// Simulate asynchronous data retrieval from the databasenew Thread(() -> {try {// Query the database based on the input parameter and send data in batchesfor (int i = 0; i < 10; i++) {String data = "Data batch " + i + " for parameter: " + inputParameter;emitter.send(data);Thread.sleep(1000); // Simulate delay between batches}emitter.complete(); // Complete the SSE connection} catch (Exception e) {emitter.completeWithError(e); // Handle errors}}).start();return emitter;}
}
  • SSM client
package sse;import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.junit.Test;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;public class TTT {CountDownLatch c = new CountDownLatch(1);@Testpublic void aaa() throws InterruptedException {String json = "{\"inputParameter\": \"1234\"}";stream("http://localhost:8080/sse/emitter", new HashMap<>(), json, new EventSourceListener() {/*@Overridepublic void onClosed(@NotNull EventSource eventSource) {System.out.println("closed");}@Overridepublic void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {System.out.println("open");}@Overridepublic void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {System.out.println(data);}*/@Overridepublic void onClosed(EventSource eventSource) {System.out.println("closed");}@Overridepublic void onOpen(EventSource eventSource, Response response) {System.out.println("open");}@Overridepublic void onEvent(EventSource eventSource, String id, String type, String data) {System.out.println("receive data: [ " + data + " ], time:" + new Date().getTime() / 1000);}});c.await();}public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");public final static int MAX_IDLE_CONNECTIONS = 20;public final static long KEEP_ALIVE_DURATION = 30L;public final static int CONNECT_TIME_OUT = 6;public final static int WRITE_TIME_OUT = 10;public final static int READ_TIME_OUT = 40;private final static OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS).writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS).readTimeout(READ_TIME_OUT, TimeUnit.SECONDS).connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES)).build();public static boolean stream(String url, Map<String, String> headers, String json, EventSourceListener eventSourceListener) {try {RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);Request.Builder builder = new Request.Builder();
//            buildHeader(builder, headers);Request request = builder.url(url).post(body).build();EventSource.Factory factory = EventSources.createFactory(HTTP_CLIENT);//创建事件
//            log.info("http stream请求,url: {},参数: {}", url, json);factory.newEventSource(request, eventSourceListener);return true;} catch (Exception e) {
//            log.error("http stream请求,url: {} 失败 ,参数: {}", url, json, e);}return false;}}
  • 测试
    启动server后运行client:
    在这里插入图片描述
    可以看到一点一点往外蹦。

写在后面

参考文章列表

springboot整合sse 。

springboot搭建流式响应服务,SSE服务端实现 。

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

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

相关文章

如何利用IPIDEA代理IP优化数据采集效率?

一、 前言二、 IPIDEA介绍三、体验步骤四、实战训练五、结语 一、 前言 在全球化与信息化交织的当代社会&#xff0c;数据已成为驱动商业智慧与技术革新的核心引擎。网络&#xff0c;作为信息汇聚与交流的枢纽&#xff0c;不仅是人们获取知识的窗口&#xff0c;更是商业活动与技…

flask sqlalchemy 多条数据删除

flasksqlalchemy 多条数据删除 在Flask-SQLAlchemy中&#xff0c;如果你想要删除多条数据&#xff0c;可以使用delete()方法配合filter()来指定条件。以下是一个删除满足特定条件的所有记录的例子&#xff1a; from flask_sqlalchemy import SQLAlchemy from your_flask_app i…

CONFIG_INITRAMFS_SOURCE

CONFIG_INITRAMFS_SOURCE 是一个内核配置选项&#xff0c;它指定了初始 RAM 磁盘&#xff08;initrd&#xff09;或初始 RAM 文件系统&#xff08;initramfs&#xff09;文件的位置&#xff0c;该文件将被 Linux 内核在启动过程中使用。值 "./usr/rootfs.cpio.lzma" …

【数据结构】详解栈

今天我们主要来了解栈&#xff01;如果对知识点有模糊&#xff0c;可翻阅以往文章哦&#xff01; 个人主页&#xff1a;小八哥向前冲~-CSDN博客 所属专栏&#xff1a;数据结构【c语言版】_小八哥向前冲~的博客-CSDN博客 c语言专栏&#xff1a;c语言_小八哥向前冲~的博客-CSDN博…

Leetcode 429:N叉树的层次遍历

给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点都由 null 值分隔&#xff08;参见示例&#xff09;。 思路&#xff1a;利用层次遍历的模板&#xff0c;直…

在sql中影响排序,但不改变字段值的方法

在order by 后面使用case … when … else … end&#xff1a; select sn, eos_date from device_table ORDER BY case when eos_date 1970-01-01 then nullelse eos_date endascnulls last上面的sql中&#xff0c;order by后面不是某个字段&#xff0c;而是一个条件表达式 c…

树和二叉树的定义和基本术语

文章目录 前言一、树的定义二、树的基本术语三、二叉树的定义总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#xff0c;便于日后复习&#xff08;这种事情不要啊&#xff09;。所用教材为《数据结构 C语言版 第2版》严蔚敏。 一、树的定义…

win7开启远程桌面却连接不上,如何解决Win7系统开启远程桌面但无法连接的问题

在使用Win7系统时&#xff0c;有时候我们可能会遇到这样的问题&#xff1a;已经成功开启了远程桌面功能&#xff0c;但尝试连接时却总是失败。这可能是由于多种原因导致的&#xff0c;下面我们将详细分析并提供相应的解决方案。 确保本地网络连接正常 可以尝试通过Ping命令测试…

C++程序设计:C++的内存分布与管理

C的内存分布与管理 栈区堆区全局区代码区常量区 栈区 &#xff08;1&#xff09;什么是栈区&#xff1f; 栈区&#xff08;Stack&#xff09; 是用于存储函数调用&#xff0c;局部变量和函数参数的一种内存区域&#xff0c;它的特性就是先进后出&#xff08;FILO&#xff09;。…

Spring底层入门(七)

1、异常处理 在DispatcherServlet中&#xff0c;doDispatch(HttpServletRequest request, HttpServletResponse response) 方法用于进行任务处理&#xff1a; 在捕获到异常后没有立刻进行处理&#xff0c;而是先用一个局部变量dispatchException进行记录&#xff0c;然后统一由…

AI电视起风,三星电视打破“隔代飞跃”,在AI纪元再次领跑

作者 | 曾响铃 文 | 响铃说 要说什么是当下最热的话题&#xff0c;刚落下帷幕的北京车展一定是其中之一&#xff0c;除了各类让人眼花缭乱的新车&#xff0c;纷至沓来的各界行业大佬&#xff0c;也让车展话题度被不断拉高。在此之外&#xff0c;此次车展还刮起了一股“旋风”…

A100 解析:为何它成为 AI 大模型时代的首选?

前言 NVIDIA A100 Tensor Core GPU 可针对 AI、数据分析和 HPC 应用场景&#xff0c;在不同规模下实现出色的加速&#xff0c;有效助力更高性能的弹性数据中心。A100 采用 NVIDIA Ampere 架构&#xff0c;是 NVIDIA 数据中心平台的引擎。A100 的性能比上一代产品提升高达 20 倍…

MySQ利用变量进行查询操作

schooldb库——utf8字符集——utf8_general_ci排序规则 先创建库&#xff0c;点击查询再去使用下列DQL。 DQL SET cityNameHaarlemmermeer; SELECT * FROM city WHER NamecityName;多个结果查询 SET cityNamesHaaelemmermeer,Breda,willemstad; SELECT cityNames; SELECT …

面试必背

数据库&#xff1a;版本 5.7.27 MySQL体系结构 6吗 SQL优化&#xff1a; 1、尽量不要select查询 * 全部信息&#xff0c;只读取所需要的字段。 2、避免前缀模糊查询。 3、 避免频繁创建和删除临时表&#xff0c;以减少系统表资源的消耗。 4、索引并不是越多越好&#xf…

QT:QT与操作系统

文章目录 信号槽与事件QT多线程概述原理完成倒计时程序 UDP回显服务器服务端客户端 信号槽与事件 在之前的信号槽中&#xff0c;已经有了一个基本的认识&#xff0c;那么对于QT中事件的理解其实就非常的类似&#xff0c;当用户进行某种操作的时候&#xff0c;就会触发事件&…

CCF-Csp算法能力认证,202206-1归一化处理(C++)含解析

前言 推荐书目&#xff0c;在这里推荐那一本《算法笔记》&#xff08;胡明&#xff09;&#xff0c;需要PDF的话&#xff0c;链接如下 「链接&#xff1a;https://pan.xunlei.com/s/VNvz4BUFYqnx8kJ4BI4v1ywPA1?pwd6vdq# 提取码&#xff1a;6vdq”复制这段内容后打开手机迅雷…

欧洲杯/奥运会-云直播

欧洲杯/奥运会要来了&#xff0c;如何升级自己的网站让你的顾客都能观赏直播已提高用户量呢&#xff1f;&#xff01; 【功能完善、平滑兼容】 云直播支持 RTMP 推流、 HLS 源站等多种直播源接入方式&#xff0c;提供直播 SDK&#xff0c;支持多终端适配&#xff0c;上行码率…

Unity之ShaderGraph入门简介与配置

前言 ShaderGraph是Unity的一个可视化着色器编辑工具,它允许开发者在不编写代码的情况下创建复杂的着色器效果。ShaderGraph提供了一个直观的图形界面,用户可以通过拖拽节点并连接它们来构建自定义的着色器。用户可以在ShaderGraph中使用各种节点,如数学运算、纹理采样、颜…

报表-接口类型的数据源

1、配置 在数据中进行如下配置 配置格式&#xff0c;换行的方式 #API $.data[0].children http://192.168.1.1:9200/apis/getInfo 行1&#xff1a;固定写法&#xff0c;标识这是一个接口类型的数据集 行2&#xff1a;JSONPath格式字符串&#xff0c;对接口的数据进行取值。…

Linux Ubuntu(玩客云) qBittorrent docker BT下载(qbittorrent 密码错误无法登录 ip地址被禁止登录等)

提示&#xff1a; 需要提前安装Docker 根据qBittorrent官网的更新日志https://www.qbittorrent.org/news &#xff0c;4.6.1.0包含一个重大更新。可以看到自4.6.1.0开始&#xff0c;qBittorrent将弃用adminadmin默认密码&#xff0c;采用随机密码&#xff0c;将在终端控制台输出…