AI 大模型统一集成|让 AI 聊天更丝滑:WebSocket 实现流式对话!_websocket支持流式吗
🌟 在这系列文章中,我们将一起探索如何搭建一个支持大模型集成项目 ChatAI 的开发过程,从 架构设计 到 代码实战,逐步搭建一个支持 多种大模型(GPT-4、DeepSeek 等) 的 一站式大模型集成与管理平台,并集成 认证中心、微服务、流式对话 等核心功能。
系列目录规划:
- ChatAI:从零开始打造你的专属大模型集成平台 ✅
- Spring Boot + OpenAI/DeepSeek:如何封装多个大模型 API 调用 ✅
- 支持流式对话 SSE & WebSocket:让 AI 互动更丝滑 ✅
- 微服务 + 认证中心:如何保障大模型 API 的安全调用
- 缓存与性能优化:提高 LLM API 响应速度
- 开源部署指南(Docker)
第四篇:让 AI 聊天更丝滑:WebSocket 实现流式对话!
在上一章中,我们使用 SSE (Server-Sent Events) 实现了 AI 生成式流式对话,但是 SSE 只能 单向推送数据,无法支持 用户在对话过程中发送控制指令(如 停止响应、调整模型、动态修改参数)。
SSE vs WebSocket 对比
📌 核心区别:
- SSE:适合 服务器推送数据,例如 AI 流式回复、日志推送、订阅通知。
- WebSocket:适合 双向交互,例如 聊天、多人协作、在线游戏。
本章,我们将升级方案,使用 WebSocket 实现 双向通信,使 AI 对话更智能、更可交互。(上一节回顾)
🌟 为什么要用 WebSocket?
与 SSE 相比,WebSocket 具有以下优点:
- 支持双向通信 🔄 —— 客户端可以随时向服务器发送消息,而不仅仅是等待 AI 回复。
- 更低的连接开销 🚀 —— WebSocket 连接后,数据传输比 SSE 高效,适用于高并发场景。
- 支持二进制数据 📡 —— 可以更灵活地发送 JSON、二进制流,适配 AI 复杂交互。
- 连接状态可控 🛠 —— 可以手动 断开连接、重连、主动停止 AI 生成。
📌 WebSocket 实现思路
-
后端:使用 Spring Boot 搭建 WebSocket 服务器,实现 AI 对话流式返回。
-
前端:用
WebSocket
对接服务器,实现 用户消息发送 & AI 流式回复。 -
增强功能:
- 支持多轮对话 🗣
- 支持手动终止 AI 响应 ⏹
- 支持 JSON 格式通信 🔄
🚀 后端实现 WebSocket 服务
1️⃣ 引入 WebSocket 依赖
在 pom.xml
添加 WebSocket 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency>
2️⃣ 创建 WebSocket 服务器
在 WebSocketChatHandler.java
实现 双向通信逻辑:
@Componentpublic class WebSocketChatHandler extends TextWebSocketHandler { private final DeepSeekClient deepSeekClient; public WebSocketChatHandler(DeepSeekClient deepSeekClient) { this.deepSeekClient = deepSeekClient; } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println(\"WebSocket 连接成功:\" + session.getId()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String userMessage = message.getPayload(); System.out.println(\"用户发送消息:\" + userMessage); try { // 调用 AI 大模型接口,并流式返回消息 deepSeekClient.streamChatWs(userMessage, session); } catch (Exception e) { session.sendMessage(new TextMessage(\"AI 服务异常,请稍后重试。\")); e.printStackTrace(); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { System.out.println(\"WebSocket 连接关闭:\" + session.getId()); }}
3️⃣ 配置 WebSocket 路由
在 WebSocketConfig.java
里开启 WebSocket 并配置路由:
@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Autowired private DeepSeekClient deepSeekClient; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new WebSocketChatHandler(deepSeekClient), \"/api/ai/chat/websocket\").setAllowedOrigins(\"*\"); }}
📌 路由说明:
- WebSocket 连接地址为
ws://localhost:8080/api/ai/chat/websocket
- 允许 所有前端域名 访问 (
setAllowedOrigins(\"*\")
)
🚀 前端实现 WebSocket 交互
1️⃣ 创建 WebSocket 连接
<script> let ws; let isStreaming = false; // 是否正在接收 AI 回复 function initWebSocket() { ws = new WebSocket(\"ws://localhost:8080/web/api/ai/chat/websocket\"); ws.onopen = function() { console.log(\"WebSocket 连接成功!\"); document.getElementById(\"stopButton\").disabled = false; // 允许停止 }; ws.onmessage = function(event) { if (!isStreaming) return; // 如果停止了,就不处理新消息 appendBotMessage(event.data); }; ws.onerror = function(error) { console.error(\"WebSocket 错误: \", error); }; ws.onclose = function() { console.log(\"WebSocket 连接关闭\"); document.getElementById(\"stopButton\").disabled = true; // 禁用停止按钮 }; } function sendMessage() { let input = document.getElementById(\"userInput\"); let message = input.value.trim(); if (message === \"\") return; let modelType = document.getElementById(\"modelType\").value; appendUserMessage(message); // 如果 WebSocket 关闭了,重新连接 if (!ws || ws.readyState === WebSocket.CLOSED) { initWebSocket(); setTimeout(() => ws.send(JSON.stringify({ modelType: modelType, message: message })), 500); } else { ws.send(JSON.stringify({ modelType: modelType, message: message })); } isStreaming = true; // 允许接收 AI 回复 input.value = \"\"; document.getElementById(\"stopButton\").disabled = false; // 启用“停止”按钮 } function stopStreaming() { isStreaming = false; // 停止接收数据 if (ws) { ws.close(); // 关闭 WebSocket 连接 } document.getElementById(\"stopButton\").disabled = true; // 禁用“停止”按钮 } function appendUserMessage(text) { let chatBox = document.getElementById(\"chatBox\"); let userMessage = document.createElement(\"div\"); userMessage.className = \"message user-message\"; userMessage.innerText = text; chatBox.appendChild(userMessage); chatBox.scrollTop = chatBox.scrollHeight; } function appendBotMessage(text) { let chatBox = document.getElementById(\"chatBox\"); let lastMessage = chatBox.lastElementChild; if (lastMessage && lastMessage.classList.contains(\"bot-message\")) { lastMessage.innerText += text; } else { let botMessage = document.createElement(\"div\"); botMessage.className = \"message bot-message\"; botMessage.innerText = text; chatBox.appendChild(botMessage); } chatBox.scrollTop = chatBox.scrollHeight; } // 初始化 WebSocket 连接 initWebSocket();</script>
2️⃣ 添加 HTML 交互界面
新增一个\"停止回答\"按钮可随时停止。
<div class=\"chat-container\"> <h1>AI 双向流式聊天</h1> <div class=\"chat-box\" id=\"chatBox\"></div> <div class=\"input-area\"> <input type=\"text\" id=\"userInput\" placeholder=\"请输入问题...\"> <select id=\"modelType\"> <option value=\"chatgpt\">ChatGPT</option> <option value=\"deepseek\">DeepSeek</option> <option value=\"local\">本地模型</option> </select> <button onclick=\"sendMessage()\">发送</button> <button id=\"stopButton\" onclick=\"stopStreaming()\" disabled>停止回答</button> </div></div>
✅ 功能测试&效果展示
-
启动 Spring Boot WebSocket 服务
-
访问
chat
页面,测试 WebSocket 交互- 发送消息
- AI 回复流式返回
- 支持手动终止连接(关闭 WebSocket)
📌 进阶优化
✅ 支持 AI 生成式内容
- 可以用
OpenAI API
或大模型
生成 流式 AI 响应 - 结合 WebSocket 分块返回,提升体验
✅ 支持会话上下文
- 维护 WebSocket 连接的 Session,实现多轮对话
✅ 实现重连机制
- WebSocket 断开时 自动重连,避免用户体验中断
🎯 总结
🎯 WebSocket 适用于:
- 实时 AI 聊天
- 流式 AI 交互
- 多轮会话管理
🎯 下一步优化:
- 结合大模型 API,让 WebSocket 支持 AI 生成式对话
- 实现 JSON 通信协议,支持更复杂交互
💡 你已经掌握 SSE + WebSocket 让你的 AI 聊天更智能!后续我们将探索 AI 生成内容的优化技巧!🔥
📢 你对这个项目感兴趣吗?欢迎 Star & 关注! 📌 GitHub 项目地址 🌟 你的支持是我持续创作的动力,欢迎点赞、收藏、分享!
📢 详细部署教程视频已更新