当前位置: 首页 > 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 应用,为用户带来全新的体验。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python办公自动化:初识 `openpyxl`
  • Ubuntu离线安装库并解决依赖关系
  • 发信息(c语言)
  • golang提案,内置 Go 错误检查函数
  • 【前端】NodeJS:记账本案例优化(token)
  • leetCode - - - 双指针
  • 解密JVM崩溃(Crash)-学习笔记
  • qt-12工具盒(ToolBox)
  • 数学基础 -- 指数增长与指数衰变
  • 使用Go语言将PDF文件转换为Base64编码
  • Wireshark分析工具
  • 构建艺术:Ruby中RESTful API的精粹实践
  • 【IDEA】idea配置服务器没有tomcat
  • 【Django开发】前后端分离django美多商城项目第1篇:欢迎来到美多 项目主要页面介绍【附代码文档】
  • SpringBoot-01-全局异常处理器
  • eclipse的离线汉化
  • ES6--对象的扩展
  • Fastjson的基本使用方法大全
  • Git的一些常用操作
  • Java Agent 学习笔记
  • php的插入排序,通过双层for循环
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 模型微调
  • 思维导图—你不知道的JavaScript中卷
  • 用Visual Studio开发以太坊智能合约
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​如何防止网络攻击?
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # Maven错误Error executing Maven
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • (1)(1.13) SiK无线电高级配置(六)
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (C++20) consteval立即函数
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Python第六天)文件处理
  • (pytorch进阶之路)扩散概率模型
  • (SpringBoot)第二章:Spring创建和使用
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (笔试题)分解质因式
  • (离散数学)逻辑连接词
  • (六)vue-router+UI组件库
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (实战篇)如何缓存数据
  • (顺序)容器的好伴侣 --- 容器适配器
  • (四)Controller接口控制器详解(三)
  • (转)fock函数详解
  • .Net core 6.0 升8.0
  • .NET Core Web APi类库如何内嵌运行?
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .Net组件程序设计之线程、并发管理(一)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?