当前位置: 首页 > news >正文

SpringBoot-模拟SSE对话交互

SpringBoot-模拟SSE对话交互

后端使用SSE进行会话,前端使用Html模拟大模型的问答交互->【前端】+【后端】


1-学习目的

本项目代码仓库:https://gitee.com/enzoism/springboot_sse

1-核心知识点

  • 1)什么是SSE协议->客户端发起一次请求,服务器保持该连接打开,并在有新数据时主动向客户端推送
  • 2)后端-开发SSE控制器
  • 3)前端-如何与SSE协议交互

2-附带知识点

  • 1)什么是请求跨域-后端如何解决跨域问题

2-动手实践

1-什么是SSE协议

SSE(Server-Sent Events)协议是一种用于在 Web 浏览器和服务器之间实现服务器向客户端单向实时通信的技术。下面将从多个方面详细介绍 SSE 协议:

1-基本概念

SSE 允许服务器在建立连接后,持续向客户端发送更新信息。与传统的请求 - 响应模式不同,在 SSE 中,客户端发起一次请求,服务器保持该连接打开,并在有新数据时主动向客户端推送。

2-工作原理
  1. 建立连接:客户端通过创建一个 EventSource 对象来向服务器发起 HTTP 请求,请求的响应头中包含 Content-Type: text/event-stream,表明这是一个 SSE 连接。
  2. 服务器推送数据:服务器保持连接打开,并在有新数据时,以特定的格式将数据发送给客户端。数据以文本流的形式传输,每条消息以两个换行符 \n\n 分隔。
  3. 客户端接收数据:客户端的 EventSource 对象会监听服务器发送的消息,并在接收到消息时触发相应的事件。
3-消息格式

SSE 消息由多个字段组成,每个字段以键值对的形式表示,字段之间用换行符分隔。常见的字段有:

  • data:表示消息的实际内容。如果消息内容较长,可以分成多行,每行以 data: 开头。
  • event:可选字段,用于指定事件类型。如果指定了事件类型,客户端可以针对不同的事件类型进行不同的处理。
  • id:可选字段,用于为消息指定一个唯一的标识符。客户端可以使用这个标识符来实现消息的断点续传。
  • retry:可选字段,用于指定客户端在连接中断后重试连接的时间间隔(以毫秒为单位)。
4-优点和缺点
  • 优点
    • 简单易用:客户端只需要创建一个 EventSource 对象,服务器端只需要按照特定的格式发送数据即可。
    • 自动重连:当连接中断时,客户端会自动尝试重新连接,并且可以使用 id 字段实现消息的断点续传。
    • 浏览器原生支持:现代浏览器都原生支持 EventSource 对象,无需额外的库或插件。
  • 缺点
    • 单向通信:SSE 只支持服务器向客户端单向通信,客户端不能向服务器发送消息。
    • 兼容性问题:虽然现代浏览器都支持 SSE,但在一些旧版本的浏览器中可能不支持。
    • 连接数量限制:浏览器对每个域名的 SSE 连接数量有一定的限制,通常为 6 个。
5-应用场景
  • 实时新闻推送:服务器可以实时向客户端推送最新的新闻消息。
  • 股票行情更新:服务器可以实时向客户端推送股票价格的变化。
  • 在线聊天系统:服务器可以实时向客户端推送新的聊天消息。

2-后端-开发SSE控制器-Java版本

1. 编写SSE控制器
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@RestController
public class ChatController {private final DeepSeekService deepSeekService;public ChatController(DeepSeekService deepSeekService) {this.deepSeekService = deepSeekService;}@GetMapping("/chat")public SseEmitter chat(@RequestParam String message) {SseEmitter emitter = new SseEmitter();ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(() -> {try {// 调用DeepSeek的chat模型deepSeekService.streamChatResponse(message, emitter);} catch (Exception e) {emitter.completeWithError(e);} finally {executorService.shutdown();}});return emitter;}
}
2. 模拟DeepSeek服务
import org.springframework.stereotype.Service;@Service
public class DeepSeekService {public void streamChatResponse(String message, SseEmitter emitter) {// 调用DeepSeek的API并流式输出try {// 模拟流式输出String[] responses = {"Hello! ", "How can I help you? ", "I'm an AI assistant."};for (String response : responses) {emitter.send(SseEmitter.event().data(response));Thread.sleep(1000); // 模拟延迟}} catch (Exception e) {emitter.completeWithError(e);}}
}

3-前端:简单的HTML/JavaScript界面

1. 创建一个前端页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>DeepSeek Chat</title><style>body { font-family: Arial, sans-serif; margin: 20px; }#messageInput { width: 300px; padding: 5px; }#response { width: 400px; height: 200px; border: 1px solid #ccc; padding: 10px; }</style>
</head>
<body><h1>DeepSeek Chat</h1><input type="text" id="messageInput" placeholder="Enter your message"><button onclick="sendMessage()">Send</button><div id="response"></div><script>let eventSource;function sendMessage() {const messageInput = document.getElementById('messageInput');const responseDiv = document.getElementById('response');const message = messageInput.value;if (message.trim() === '') return;responseDiv.innerHTML = '';// 创建一个新的EventSourceeventSource = new EventSource(`/chat?message=${encodeURIComponent(message)}`);eventSource.onmessage = function (event) {responseDiv.innerHTML += event.data;};eventSource.onerror = function (error) {console.error('EventSource error:', error);eventSource.close();};}</script>
</body>
</html>

3-其他版本SSE-NodeJs

1-服务器端代码示例(Node.js + Express)

const express = require('express');
const app = express();app.get('/sse', (req, res) => {res.setHeader('Content-Type', 'text/event-stream');res.setHeader('Cache-Control', 'no-cache');res.setHeader('Connection', 'keep-alive');res.flushHeaders();let counter = 0;const intervalId = setInterval(() => {res.write(`data: Message ${counter}\n\n`);counter++;}, 1000);req.on('close', () => {clearInterval(intervalId);});
});const port = 3000;
app.listen(port, () => {console.log(`Server running on port ${port}`);
});

2-客户端代码示例(JavaScript)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8">
</head><body><div id="messages"></div><script>const eventSource = new EventSource('/sse');eventSource.onmessage = function (event) {const messagesDiv = document.getElementById('messages');const newMessage = document.createElement('p');newMessage.textContent = event.data;messagesDiv.appendChild(newMessage);};eventSource.onerror = function (error) {console.error('EventSource failed:', error);};</script>
</body></html>

相关文章:

SpringBoot-模拟SSE对话交互

SpringBoot-模拟SSE对话交互 后端使用SSE进行会话&#xff0c;前端使用Html模拟大模型的问答交互->【前端】【后端】 1-学习目的 本项目代码仓库&#xff1a;https://gitee.com/enzoism/springboot_sse 1-核心知识点 1&#xff09;什么是SSE协议->客户端发起一次请求&am…...

删除链表的倒数第N个节点 力扣19

一、题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 3&a…...

IvorySQL v4 逻辑复制槽同步功能解析:高可用场景下的数据连续性保障

功能简介 IvorySQL v4 基于 PostgreSQL 17&#xff0c;引入了逻辑复制槽同步至热备份数据库的功能。这一改进有效解决了旧版本中主数据库与备份数据库切换后逻辑复制中断的问题。对于那些追求数据高可用性和业务连续性的数据库来说&#xff0c;这无疑是一个重大的利好消息。它…...

vxe-table开启表尾和el-collapse-transition不兼容,动画卡顿

调用控制台 发现是el-collapse-transition内置的计算高度函数计算的高度总是会高一点 直接放弃使用el-collapse-transition 使用下面的div包裹住vxe-table 我的table是渲染出来的会有多个 <el-button click"group.messShow !group.messShow" type"text&q…...

康谋分享 | 3DGS:革新自动驾驶仿真场景重建的关键技术

随着自动驾驶技术的迅猛发展&#xff0c;构建高保真、动态的仿真场景成为了行业的迫切需求。传统的三维重建方法在处理复杂场景时常常面临效率和精度的挑战。在此背景下&#xff0c;3D高斯点阵渲染&#xff08;3DGS&#xff09;技术应运而生&#xff0c;成为自动驾驶仿真场景重…...

golang学习笔记——go语言安装及系统环境变量设置

文章目录 go语言安装go envgo getgoproxy测试安装 Go 插件安装 Go 插件依赖工具参考资料用户环境变量和系统环境变量用户环境变量系统环境变量示例设置环境变量的步骤设置用户环境变量设置系统环境变量 验证环境变量总结 2024年最火的5大Go框架1. Gin&#xff1a;高并发接口的“…...

Redis|集群 Cluster

文章目录 是什么能干嘛集群算法-分片-槽位slotredis集群的槽位slotredis集群的分片分片槽位的优势slot槽位映射——业界的3种解决方案小厂&#xff1a;哈希取余分区中厂&#xff1a;一致性哈希算法分区大厂&#xff1a;哈希槽分区 面试题&#xff1a;为什么 Redis 集群的最大槽…...

解锁MacOS开发:环境配置与应用开发全攻略

✨✨✨这里是小韩学长yyds的BLOG(喜欢作者的点个关注吧) ✨✨✨想要了解更多内容可以访问我的主页 小韩学长yyds-CSDN博客 目录 引言 一、MacOS 开发环境配置 &#xff08;一&#xff09;必备工具安装 &#xff08;二&#xff09;集成开发环境&#xff08;IDE&#xff09;选…...

如何通过卷积神经网络(CNN)有效地提取图像的局部特征,并在CIFAR-10数据集上实现高精度的分类?

目录 1. CNN 提取图像局部特征的原理 2. 在 CIFAR - 10 数据集上实现高精度分类的步骤 2.1 数据准备 2.2 构建 CNN 模型 2.3 定义损失函数和优化器 2.4 训练模型 2.5 测试模型 3. 提高分类精度的技巧 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#…...

监听 RabbitMQ 延时交换机的消息数、OpenFeign 路径参数传入斜杠无法正确转义

背景 【MQ】一套为海量消息和高并发热点消息&#xff0c;提供高可用精准延时服务的解决方案 我现在有一个需求&#xff0c;就是监听 RabbitMQ 一个延时交换机的消息数&#xff0c;而 RabbitTemplate 是不存在对应的方法来获取的。 而我们在 RabbitMQ 的控制台却可以发现延时交…...

希音(Shein)前端开发面试题集锦和参考答案

用 Node 写过什么工具或 npm 包 在实际开发中,使用 Node 编写过多种实用工具和 npm 包。 自动化构建工具 开发了一个简单的自动化构建工具,用于处理前端项目的资源压缩和合并。在前端项目中,为了优化性能,需要对 CSS 和 JavaScript 文件进行压缩,减少文件体积,同时将多个…...

python全栈-Linux基础

python全栈-Linux基础 文章目录 Linux安装/配置网络配置配置Linux远程登录配置虚拟机内部ip配置真机的ip安装XShell和Xftp目录结构用户和用户组用户管理添加用户useradd查看用户id修改用户usermod (选项)(参数)用户密码设置passed (选项)(参数)删除用户userdel [选项] 用户名 用…...

DeepSeek R1助力,腾讯AI代码助手解锁音乐创作新

目录 1. DeepSeekR1模型简介2. 歌词创作流程2.1 准备工作2.2 歌词生成技巧 3. 音乐制作环节3.1 主流AI音乐生成平台 4. 歌曲欣赏5. 总结展望 1. DeepSeekR1模型简介 腾讯AI代码助手最新推出的DeepSeekR1模型不仅在代码生成方面表现出色&#xff0c;其强大的自然语言处理能力也…...

Git安装与配置

安装部分&#xff1a; Windows&#xff1a;下载官网安装包&#xff0c;双击安装&#xff0c;路径选择&#xff08;注意是否修改&#xff09;&#xff0c;安装选项&#xff08;是否勾选某些选项&#xff0c;如提到安装时更换编辑器为Nano&#xff09;。Linux&#xff1a;通过包管…...

【Linux】自定协议和序列化与反序列化

目录 一、序列化与反序列化概念 二、自定协议实现一个加法网络计算器 &#xff08;一&#xff09;TCP如何保证接收方的接收到数据是完整性呢&#xff1f; &#xff08;二&#xff09;自定义协议 &#xff08;三&#xff09;自定义协议的实现 1、基础类 2、序列化与反序列…...

C++基础系列【19】运算符重载

博主介绍&#xff1a;程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章&#xff0c;首发gzh&#xff0c;见文末&#x1f447;&#x1f…...

Python-04BeautifulSoup网络爬虫

2025-03-04-BeautifulSoup网络爬虫 记录BeautifulSoup网络爬虫的核心知识点 文章目录 2025-03-04-BeautifulSoup网络爬虫 [toc]1-参考网址2-学习要点3-核心知识点1. 安装2. 导入必要的库3. 发送 HTTP 请求4. 创建 BeautifulSoup 对象5. 解析 HTML 内容5.1 查找标签5.2 根据属性…...

芯科科技通过全新并发多协议SoC重新定义智能家居连接

MG26系列SoC现已全面供货&#xff0c;为开发人员提供最高性能和人工智能/机器学习功能 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;&#xff0c;日前宣…...

python-leetcode-零钱兑换 II

518. 零钱兑换 II - 力扣&#xff08;LeetCode&#xff09; 这个问题是 完全背包问题 的一个变体&#xff0c;可以使用 动态规划 来解决。我们定义 dp[i] 为凑成金额 i 的硬币组合数。 思路&#xff1a; 定义 DP 数组 设 dp[i] 表示凑成金额 i 的组合数&#xff0c;初始化 dp[…...

【RabbitMQ】Producer之TTL过期时间 - 基于AMQP 0-9-1

这篇文章和大家分享Producer发布消息时如何设置消息过期时间&#xff0c;包括队列级别和消息级别&#xff0c;还有如何设置队列的过期时间。 消息过期时间 给消息设置TTL&#xff0c;在超过TTL值后&#xff0c;消息就会变成dead message&#xff08;死信&#xff09;&#xf…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...