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

打造聊天流式回复效果:Spring Boot+WebSocket + JS实战

本篇博客将带领你使用 Spring Boot、WebSocket 和 JavaScript 实现一个类似 ChatGPT 的流式回复效果。前端发送消息后,后端接收消息并请求 AI API,并将 AI 返回的流式响应实时推送到前端,最终在聊天界面呈现出逐字出现的打字效果。

技术原理

  1. WebSocket 全双工通信: WebSocket 协议提供全双工通信通道,允许服务器和客户端之间进行双向实时数据传输,非常适合实现流式数据传输。

  2. Spring WebFlux 响应式编程: Spring WebFlux 基于 Reactor 库,支持响应式流处理,可以处理 AI API 返回的流式数据。

  3. SSE(Server-Sent Events): SSE 是一种基于 HTTP 的单向服务器推送技术,可以将 AI 返回的流式数据实时推送到前端。

实现步骤

一、后端实现 (Spring Boot)
  1. 添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
  1. 创建 WebSocket 处理器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;import java.time.Duration;@Controller
public class ChatController {@Autowiredprivate SimpMessagingTemplate messagingTemplate;@Autowiredprivate WebClient webClient; // 用于调用 AI API@MessageMapping("/chat.sendMessage") // 接收来自客户端的消息public void sendMessage(@Payload Message message) throws Exception {// 构造 AI API 请求ApiRequest apiRequest = new ApiRequest(message.getContent()); // 假设 AI API 接受 ApiRequest 对象// 调用 AI API,获取流式响应Flux<String> apiResponse = callAiApi(apiRequest);// 处理 AI API 响应,并逐条发送给前端apiResponse.delayElements(Duration.ofMillis(50)) // 模拟打字延迟.subscribe(chunk -> {Message responseMessage = new Message("AI", chunk);messagingTemplate.convertAndSend("/topic/chat", responseMessage);});}// 调用 AI APIprivate Flux<String> callAiApi(ApiRequest request) {// 将 ApiRequest 对象转换为 JSON 字符串// ...// 发送 POST 请求,并指定返回数据类型为 Flux<String>return webClient.post().uri("https://api.example.com/ai-api") // 替换为实际的 AI API 地址.bodyValue(request).retrieve().bodyToFlux(String.class);}// 消息类public static class Message {private String sender;private String content;// 构造函数,getter 和 setter}// AI API 请求类public static class ApiRequest {private String prompt;// 构造函数,getter 和 setter}
}
  1. WebSocket 配置
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic");config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws").withSockJS();}
}
二、前端实现 (JavaScript)
<!DOCTYPE html>
<html>
<head><title>Chat Application</title><script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body><div id="chat-container"><div id="chat-output"></div><input type="text" id="message-input" placeholder="Enter message..."><button onclick="sendMessage()">Send</button></div><script>// 连接 WebSocketvar socket = new SockJS('/ws');var stompClient = Stomp.over(socket);stompClient.connect({}, function(frame) {console.log('Connected: ' + frame);// 订阅聊天频道stompClient.subscribe('/topic/chat', function(message) {showMessage(JSON.parse(message.body));});});// 发送消息function sendMessage() {var message = document.getElementById('message-input').value;stompClient.send("/app/chat.sendMessage", {}, JSON.stringify({'sender': 'user', // 可替换为实际用户名'content': message}));}// 显示消息function showMessage(message) {var chatOutput = document.getElementById('chat-output');var messageElement = document.createElement('div');if (message.sender === 'AI') {// AI 回复逐字显示typeWriter(messageElement, message.content, 0);} else {messageElement.innerHTML = '<strong>' + message.sender + ':</strong> ' + message.content;chatOutput.appendChild(messageElement);}}// 模拟打字效果function typeWriter(element, text, i) {if (i < text.length) {element.innerHTML += text.charAt(i);setTimeout(function() {typeWriter(element, text, i + 1);}, 50); // 调整打字速度} else {document.getElementById('chat-output').appendChild(element);}}</script>
</body>
</html>

总结

本文介绍了如何使用 Spring Boot 和 WebSocket 实现类似 ChatGPT 的流式回复效果,并详细讲解了每个步骤的技术原理和代码实现。通过这种方式,我们可以构建更加 engaging 和 interactive 的 Web 应用,为用户带来全新的体验。

相关文章:

打造聊天流式回复效果:Spring Boot+WebSocket + JS实战

本篇博客将带领你使用 Spring Boot、WebSocket 和 JavaScript 实现一个类似 ChatGPT 的流式回复效果。前端发送消息后&#xff0c;后端接收消息并请求 AI API&#xff0c;并将 AI 返回的流式响应实时推送到前端&#xff0c;最终在聊天界面呈现出逐字出现的打字效果。 技术原理…...

202年版最新Python下载安装+PyCharm下载安装激活和使用教程!(附安装包+激活码)

一、Python解释器下载【运行环境】 Python官网&#xff1a; https://www.python.org Python各版本解释器官网&#xff1a; https://www.python.org/downloads/ 二、Windows系统安装Python解释器 下载Python版本解释器 现在已经更新到了3.13版本的Python解释器&#xff0c;但…...

【面试宝典】spring常见面试题总结[上]

一、什么是 Spring 框架&#xff1f; Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。 Spring 帮助开发者解决基础性的问题&#xff0c;使开发者专注编写业务代码。 二、Spring Freamework 有哪些功能&#xff1f; IOC: 控制反转AOP: 面…...

NC单链表的排序

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个节点…...

阿里云部署open-webui实现openai代理服务(持续更新)

一、展示 xiezhaoxuan.top:8080 二、 环境准备 1. 阿里云服务器,ubuntu22系统 2. http代理(可访问外网) 3. openai API Key 三、实际操作记录(阿里云服务器端) 1. 根据官方文档安装open-webui服务端(看完这节再操作): 🚀 Getting Started | Open WebUI 1. 如果服务器配置比较…...

Vue3简介和快速体验

文章目录 前言1. Vue3介绍2. Vue3快速体验(非工程化方式) 前言 本次主要用VScode开发代码&#xff0c;vscode的安装很简单&#xff0c;不会的可以查询一下网上的资料 1. Vue3介绍 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于…...

LeetCode98 验证二叉搜索树

前言 题目&#xff1a; 98. 验证二叉搜索树 文档&#xff1a; 代码随想录——验证二叉搜索树 编程语言&#xff1a; C 解题状态&#xff1a; 对中序遍历理解不到位 思路 了解了中序遍历会返回一个有序数组后&#xff0c;本题就可以迎刃而解。只需要判断&#xff0c;返回的数组…...

llama的神经网络结构;llama的神经网络结构中没有MLP吗;nanogpt的神经网络结构;残差是什么;残差连接:主要梯度消失

目录 解释代码 潜在问题和修正 结论 llama的神经网络结构 神经网络结构概述 举例说明 llama的神经网络结构中没有MLP吗 nanogpt的神经网络结构 1. 词嵌入层(Embedding Layer) 2. Transformer编码器层(Transformer Encoder Layer) 3. 层归一化(Layer Normalizat…...

函数的常量引用入参const saclass sdf,可否传入一个指向saclass对象的指针 shared_ptr<saclass>

不可以直接将一个指向 saclass 对象的 shared_ptr<saclass> 作为参数直接传入一个期望 const saclass& 类型参数的函数。原因是类型不匹配&#xff1a;shared_ptr<saclass> 是一个智能指针类型&#xff0c;它封装了对 saclass 对象的指针&#xff0c;并提供了一…...

数据库:SQL——数据库操作的核心语言

数据库&#xff1a;SQL——数据库操作的核心语言 SQL&#xff08;结构化查询语言&#xff09;是关系型数据库管理系统中的标准语言&#xff0c;广泛用于数据的定义、操作、控制和查询。SQL 包含多个子语言&#xff0c;分别用于不同的数据库操作任务&#xff0c;包括数据定义&a…...

Unity + HybridCLR 从零开始

官方文档开始学习,快速上手 | HybridCLR (code-philosophy.com)是官方文档链接 1.建议使用2019.4.40、2020.3.26、 2021.3.0、2022.3.0 中任一版本至于其他2019-2022LTS版本可能出现打包失败情况 2. Windows Win下需要安装visual studio 2019或更高版本。安装时至少要包含 使…...

C++小总结

C小总结 接口 对外暴露头文件中&#xff0c;只需要声明接口函数即可&#xff0c;其他不暴露的函数不需要进行声明。接口的参数使用指针形式比较好&#xff0c;因为外部使用时可以对实参进行创建和析构&#xff0c;如果非接口函数使用new开辟&#xff0c;不太好进行析构。在使…...

从快到慢学习Git指令

Git是现在最流行的版本控制工具之一。无论是在开源社区还是企业软件开发中,Git都扮演着至关重要的角色。本文将根据不同的需求,分别提供快速上手和深入学习Git的指南。 如果你只想下载代码 如果你只是想下载GitHub或其他代码仓库的代码,那你只需要了解以下两个命令: git clo…...

传奇游戏发布渠道

传奇游戏发布渠道 回答&#xff1a;游戏发布平台|手机游戏发布平台 传奇游戏发布渠道作为游戏开发商直接控制的信息传播途径&#xff0c;其安全性自然有着较高的保障。首先&#xff0c;渠道通常会采用先进的加密技术和安全协议来保护数据传输过程中的安全&#xff0c;防止信息…...

如何有效阅读科研论文【方法论】

如何读论文【论文精读1】_哔哩哔哩_bilibili 如何有效阅读科研论文 科研论文是了解学术领域最新研究成果和技术发展的重要途径。有效地阅读论文不仅能够帮助我们掌握前沿知识&#xff0c;还能提升自己的研究能力。本文将介绍一种系统的论文阅读方法&#xff0c;并通过具体的步…...

【揭秘】层层加码,竟能加速渠道营销数字化?-eBest

国潮饮料品牌在eBest RTM系统的支持下&#xff0c;已经将数字化贯彻到每一个销售环节&#xff0c;且看eBest如何通过“层层加码”&#xff0c;进一步加速该饮料品牌渠道数字化进程&#xff0c;实现弯道超车&#xff1f; “一箱四码”垛码 五码实现渠道数字化 为提高营销和数字…...

基于WAMP环境的简单用户登录系统实现(v3版)(持续迭代)

目录 版本说明 实现环境&#xff1a; 流程逻辑框图&#xff1a; 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;doLogin.php 用户欢迎页面&#xff1a;welcome.php 密码修改页面&#xff1a;change_password.html 修改处理&#xff1a;doChangePa…...

大语言模型与多模态大模型loss计算

文章目录 前言一、大语言模型loss计算1、loss计算代码解读2、构建模型输入内容与label标签3、input_ids与labels格式 二、多模态大模型loss计算方法1、多模态loss计算代码解读2、多模态输入内容2、大语言模型输入内容3、图像embending如何嵌入文本embeding 前言 如果看了我前面…...

线上研讨会 | CATIA助力AI提升汽车造型设计

报名链接&#xff1a; 2024探索之旅第二季...

Unity新输入系统 之 InputAction(输入配置文件最基本的单位)

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 首先你应该了解新输入系统的构成结构&#xff1a;Unity新输入系统结构概览-CSDN博客 Input System - Unity 手册 1.In…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...