VUE3和SpringBoot实现ChatGPT页面打字效果SSE流式数据展示

在做这个功能之前,本人也是走了很多弯路(花了好几天才搞好),你能看到本篇博文,那你就是找对地方了。百度上很多都是使用SseEmitter这种方式,这种方式使用的是websocket,使用这种方式就搞复杂了,会为后面项目分布式布署上埋下坑,什么坑,下面会说明。要实现【VUE3和SpringBoot实现ChatGPT页面打字效果SSE流式数据展示】这种效果,其实就是要使用SSE这种协议,这种协议很简单。我们先明白websocket和sse有什么区别,说几个主要的区别(太细的自己百度,这不是本博文的重点)

1、SSE是一种基于HTTP的单向通信机制,用于服务器向客户端推送数据,是单向通信

2、WebSocket是一种全双工的通信协议,它通过在客户端和服务器之间建立持久连接,实现双向通信

3、使用SSE在SpringBoot端,就像平时写接口一样,不需要啥配置,不需要保存用户的连接Session,WebSocket在SpringBoot端配置太多,而且需要保存用户的连接session,保存连接seesion在分布式布署上就比较麻烦。

博文最后会有整个项目源代码下载地址,下载之后里面有两个文件夹,myserver是后端springboot的,myweb是vue3前端页面的,如下截图

一、先看效果

二、环境搭建

1、在使用之前,我们还是安装一个大模型,我们这里使用的是LmStudio工具,这里面可以下载阿里开源的通义千问的语言模型,而且是在windows操作,简单;

2、下载地址:https://releases.lmstudio.ai/windows/0.2.17/latest/LM-Studio-0.2.17-Setup.exe

3、安装之后,就是下载大模型(下载需要魔法上网),选择Qwen 1.5

4、启动大模型,按箭头顺序,大模型启动后端口是1234

三、后端服务SpringBoot实现

用idea打开myserver项目,直接运行ServerApplication这个类,关键代码如下:


        //构建请求对象
        ChatRequest chatRequest = new ChatRequest();
        chatRequest.setModel("qwen:latest");//设置模型
        chatRequest.setStream(true);//设置流式返回

        ReqMessage reqMessage = new ReqMessage();//设置请求消息,在此可以加入自己的prompt
        reqMessage.setRole("user");//用户消息
        reqMessage.setContent(message);//用户请求内容
        ArrayList<ReqMessage> messageList = new ArrayList<>();
        messageList.add(reqMessage);
        chatRequest.setMessages(messageList);//设置请求消息
        //构建请求json
        String paramJson = JSONUtil.toJsonStr(chatRequest);;

        Flux<String> response = webClient.post()
                .uri("/chat/completions")//请求uri
                .header("Authorization", "Bearer sk-**************")//设置成自己的key,获得key的方式可以在下文查看
                .header(HttpHeaders.ACCEPT, MediaType.TEXT_EVENT_STREAM_VALUE)//设置流式响应
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(paramJson))
                .retrieve()
                .bodyToFlux(String.class)
                .flatMap(res->{
                    if (StrUtil.equals("[DONE]",res)){//[DONE]是消息结束标识
                        return Flux.empty();
                    }
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        //System.out.println(res);
                        JsonNode jsonNode = objectMapper.readTree(res);
                        Answer aiAnswer = objectMapper.treeToValue(jsonNode, Answer.class);
                        List<Choices> choicesList = aiAnswer.getChoices();
                        Choices choices = choicesList.get(0);
                        Delta delta = choices.getDelta();
                        String json = objectMapper.writeValueAsString(delta);
                        System.out.println(json);
                        return Flux.just(json);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }

                    return Flux.empty();
                });

三、Vue3前端关键代码

1、打开myweb项目,先cmd命令,进入到当前目录执行如下命令

npm install

2、运行项目,执行如下命令

npm run dev

3、前端页面关键代码

const abortController = new AbortController();
  eventSource.value = fetchEventSource('http://localhost:8080/ck/chat?message='+sendMsg.value,
      {
        method: "GET",
        signal: abortController.signal,
        openWhenHidden: true,
        onmessage(event) {
          let res = event.data;
          console.log(res)
          if(res!='[DONE]'&&res!=null){
            let data = JSON.parse(event.data);
            let content = data.content
            console.log('content=='+content)
            if(content!=null&&content.indexOf('\n')!=-1){
              let text = tableRightData.value[tableRightData.value.length - 1].content + content
              content = DOMPurify.sanitize(marked.parse(text))
              tableRightData.value[tableRightData.value.length - 1].content = content
              tableRightData.value.push({"role": "assistant", "content": '', "showPhoto": false, "error": null});
            }else if(content!=null&&content!=''){
              tableRightData.value[tableRightData.value.length - 1].content += content
            }
          }
          nextTick(()=>{
            //滚动条置最下面
            const container = rightContainerRef.value
            container.scrollTop = container.scrollHeight
          })
        },
        onclose() {
          console.log('结束了***************************')
          deleteBlankRow()
          // eventSource.close();
          eventSource.value = null; // 重置eventSource变量,允许重建连接
          console.log('结束了2*****************')
          abortController.abort();


        },
        onerror(event){
          console.log("EventSource failed:", event);
          abortController.abort();
          eventSource.value.close(); // 关闭出错的连接
          eventSource.value = null; // 重置eventSource变量,允许重建连接
        }
      }
  );

四、源代码下载:

下载地址:百度网盘 请输入提取码

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32 PWM方式读取AS5600磁编码器数据

HAL STM32 PWM方式读取AS5600磁编码器获取角度例程 &#x1f4cd;相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》 &#x1f4cc;《HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程》 &#x1f341;先通过IIC读取的角度值和逻辑分析仪抓取的AS5600 OUT引脚…

MySQL - 基础二

6、表的增删改查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 6.1、Create 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)]VALUES (value_list) [, (value_list)] ...value_list: v…

SQL注入---盲注

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.盲注概述 注是一种SQL注入攻击的形式&#xff0c;在这种攻击中&#xff0c;攻击者向目标应用程序发送恶意注入代码&#xff0c;然后通过观察应用程序的响应来推断出数据库中的信息。与常规的…

@Order和@DependsOn的区别

这里写自定义目录标题 一、区别二、demo演示1、Order2、DependsOn 一、区别 Order&#xff1a;改变Bean注入的顺序DependsOn&#xff1a;改变Bean创建的顺序 二、demo演示 1、Order 类 A B 都实现了接口 I &#xff0c;且 A B都由Spring容器创建并且管理 public class A im…

【Qt】:常用控件(二:QWidget核心属性)

常用控件&#xff08;二&#xff09; 一.cursor&#xff08;光标形状&#xff09;二.font&#xff08;字体信息&#xff09;三.toolTip&#xff08;提示显示&#xff09;四.focusPolicy&#xff08;焦点&#xff09;五.styleSheet&#xff08;文本样式&#xff09; 一.cursor&a…

Windows Docker 部署 Firefly III 开源记账软件

一、简介 Firefly III是一款开源的记账软件&#xff0c;支持全球多种语言。它可以帮助用户追踪和管理个人账目、预算和账单&#xff0c;减少支出&#xff0c;节省更多。该软件支持多种货币、银行账户和投资账户&#xff0c;并提供了丰富的报表功能&#xff0c;帮助用户更好地了…

预处理指令详解

前言 上一节我们了解了文件操作的相关内容&#xff0c;本节我们来了解一下预处理指令&#xff0c;那么废话不多说&#xff0c;我们正式开始今天的学习 预定义符号 在C语言中&#xff0c;设置了一些预定义的符号&#xff0c;可以供我们直接使用&#xff0c;预定义符号是在程序…

拓扑排序--有向无环图中一个节点的所有祖先

题目描述 给你一个正整数 n &#xff0c;它表示一个 有向无环图 中节点的数目&#xff0c;节点编号为 0 到 n - 1 &#xff08;包括两者&#xff09;。 给你一个二维整数数组 edges &#xff0c;其中 edges[i] [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。 请你返…

基于SpringBoot和Vue的金融融资管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

图像处理入门 3(how to get the pixel pitch / 如何获得单个像素的尺寸)

在这里一节里面&#xff0c;将记录如何获得一个相机传感器中单个像素点的尺寸&#xff0c;为了实现不同相机照片之间的匹配。 如果我们知道了相机传感器的尺寸和分辨率的大小&#xff0c;自然就可以求出单个像素的大小。 在这里插入图片描述&#xff1a; 如何获得相机传感器的…

读《Spring实战》:面向切面

AOP术语 通知&#xff08;Advice&#xff09; 在AOP中&#xff0c;切面的工作被称为通知&#xff0c;也就是通知就是具体要干的工作。 spring中有5中通知&#xff1a; 前置通知&#xff1a; 在目标方法之前调用通知功能后置通知&#xff1a; 在目标方法之后调用通知功能返回…

SQL Server维护计划

目录 1.概述 2.启动SQL Server 代理服务 3.制定维护计划 4.验证维护计划 5.删除维护计划 1.概述 此文还是存货哈&#xff01; SQL Server 2008 R2维护计划。 2.启动SQL Server 代理服务 在设置维护计划之前&#xff0c;必须先确保SQL Server 代理服务已启动。启动方法如…

FastAPI Web框架教程 第12章 异步async-await

12-1 fastapi是异步Web框架 从本教程开篇&#xff0c;我们就说FastAPI这个web框架是异步框架&#xff0c;那它到底是如何体现异步的呢&#xff1f; 想要学习使如何使用FastAPI的异步功能&#xff0c;那就必须要先了解什么是异步&#xff0c;什么是asyncio、async/await 【基…

BoostCompass —— 搜索引擎

文章目录 一、项目简介二、Boost库简介1. 简介2. Boost 库的特点 三、项目主要模块1. 网页内容获取&#xff0c;数据预处理模块2. 建立正排索引和倒排索引&#xff0c;项目核心模块3. 编写 http_server 模块&#xff0c;进行网络开放 四、项目功能预览1. 项目文件预览2. 项目执…

基于储能电站服务的冷热电多微网系统 双层优化配置

目录 一、主要内容 二、部分代码 三、程序结果 四、下载链接 一、主要内容 随着储能技术的进步和共享经济的发展&#xff0c;共享储能电站服务模式将成为未来用户侧储能应用的新形态。提出基于储能电站服务的冷热电联供型多微网系统双层优化配置方法。 首先&#xff0c;提出…

【深入理解计算机系统第3版】有符号数和无符号数转换以及移位运算练习题2.23

题目 考虑下面的C函数&#xff1a; int fun1(unsigned word) {return (int) ((word << 24) >> 24); }int fun2(unsigned word) {return ((int) word << 24) >> 24; } 假设一个采用补码运算的机器上以32位程序来执行这些函数。还假设有符号数值的右移…

C易错注意之const修饰指针,含char类型计算,位段及相关经典易错例题

目录 前言 一&#xff1a;const修饰指针 1.const修饰变量 2.const 修饰指针 1.const int*p&m; 2. int* const p&m; 3. int const *p&m; 4. int const *const p&m; 5.总结 总之一句话为&#xff1a;左定值有定向 二&#xff1a;关于计算中char类型…

前端开发基础(HTML5 + CSS3)【第一篇】:HTML标签之文字排版、图片、链接、音频、视频 涵盖了两个综合案例 做到了基础学得会,实战写的出

点击前往前端开发基础专栏&#xff1a; 文章目录 HTML5 CSS3 开发一、开发环境搭建下载 VS Code1. 2 插件的下载1.3 项目和文件的下载 二、 什么是 HTML2.1 标签的语法2.2 代码演示&#xff1a;2.3 小结 三 、HTML基本骨架3.1 快捷键生成HTML骨架3.2 代码展示3.3 小结 四、标…

AI绘画:实例-利用Stable Diffusion ComfyUI实现多图连接:区域化提示词与条件设置

在Stable Diffusion ComfyUI中&#xff0c;有一种高级技巧可以让用户通过细致的区域化提示词来控制图像的不同部分&#xff0c;从而实现多图连接的效果。这种方法允许艺术家在同一画布上展现多个场景&#xff0c;创造出富有层次和故事性的图像。以下是实现这一效果的详细步骤。…

Transformer模型-Multi-Head Attention多头注意力的简明介绍

今天介绍transformer模型的Multi-Head Attention多头注意力。 原论文计算scaled dot-product attention和multi-head attention 实际整合到一起的流程为&#xff1a; 通过之前文章&#xff0c;假定我们已经理解了attention&#xff1b;今天我们按顺序来梳理一下整合之后的顺序。…