uniapp+node+mysql接入deepseek实现流式输出
node
import express from 'express';
import mysql from 'mysql2';
import cors from 'cors';
import bodyParser from 'body-parser';
import axios from 'axios';
import { WebSocketServer } from 'ws'; // 正确导入 WebSocketServerconst app = express();// Middlewares
app.use(cors());
app.use(bodyParser.json()); // 解析JSON请求体
app.use(express.json());// MySQL数据库配置
const db = mysql.createConnection({host: '127.0.0.1',user: 'root',password: '123456',database: 'love_strategist',port: 3307,
});db.connect((err) => {if (err) throw err;console.log('✅ MySQL 连接成功');
});// 创建 WebSocket 服务器
const wss = new WebSocketServer({ port: 8080 }); // 使用 WebSocketServerwss.on('connection', (ws) => {console.log('客户端已连接');ws.on('message', async (message) => {const { message: userMessage } = JSON.parse(message);try {const response = await axios.post('https://api.deepseek.com/v1/chat/completions',{model: "deepseek-chat",messages: [{ role: "user", content: userMessage }],stream: true},{headers: {'Authorization': `Bearer 你的deepseekKey`,'Content-Type': 'application/json'},responseType: 'stream'});let buffer = ''; // 用于存储未完整的数据块response.data.on('data', (chunk) => {buffer += chunk.toString(); // 将数据块拼接到缓冲区// 按行分割数据const lines = buffer.split('\n');for (let i = 0; i < lines.length - 1; i++) {const line = lines[i].trim();if (line.startsWith('data: ')) {const jsonStr = line.replace('data: ', '');try {const data = JSON.parse(jsonStr);if (data.choices?.[0]?.delta?.content) {// 逐字发送内容const content = data.choices[0].delta.content;ws.send(JSON.stringify({ content }));}} catch (error) {console.error('解析JSON失败:', error);}}}// 保留未完整的数据行buffer = lines[lines.length - 1];});response.data.on('end', () => {ws.send(JSON.stringify({ content: '[DONE]' }));});} catch (error) {console.error('Error:', error);ws.send(JSON.stringify({ content: '系统错误,请稍后再试。' }));}});ws.on('close', () => {console.log('客户端已断开连接');});
});// 启动 HTTP 服务器
app.listen(3000, () => {console.log('✅ HTTP 服务器运行在 http://localhost:3000');
});console.log('WebSocket 服务器运行在 ws://localhost:8080');
uniapp
<template><view class="container"><!-- 顶部导航栏 --><view class="navbar">恋爱指导</view><!-- 聊天对话区域 --><scroll-view class="chat-box" scroll-y :style="{ height: (chatHeight - 70) + 'px' }" scroll-top="999999"><view v-for="(message, index) in messages" :key="index" class="chat-item"><view :class="message.from === 'user' ? 'user-message' : 'bot-message'"><text>{{ message.content }}</text></view></view></scroll-view><!-- 输入框区域 --><view class="input-area"><input v-model="userInput" class="input-box" placeholder="请输入你的问题..." /><button class="send-btn" @click="sendMessage">发送</button></view></view>
</template><script>export default {data() {return {userInput: '', // 用户输入的消息messages: [], // 存储消息记录chatHeight: 0, // 聊天框高度adviceList: [], // 存储恋爱建议socket: null // WebSocket 实例};},mounted() {this.adjustChatHeight(); // 调整聊天框高度},onShow() {setTimeout(() => {this.initWebSocket(); // 初始化 WebSocket}, 300)},// 页面隐藏时关闭 WebSocketonHide() {if (this.socket) {this.socket.close(); // 关闭 WebSocketconsole.log('WebSocket 连接已关闭');}},methods: {// 选中标签填充输入框并发送selectAdvice(content) {this.userInput = content;this.sendMessage();},// 动态计算聊天框高度adjustChatHeight() {const windowHeight = uni.getSystemInfoSync().windowHeight;this.chatHeight = windowHeight - 120; // 留出顶部和输入框的高度},// 初始化 WebSocket 连接initWebSocket() {this.socket = uni.connectSocket({url: 'ws://localhost:8080',success: () => {console.log('WebSocket 连接成功4');},fail: (err) => {console.error('WebSocket 连接失败:', err);}});// 监听 WebSocket 消息this.socket.onMessage((res) => {const data = JSON.parse(res.data);if (data.content === '[DONE]') {this.isStreaming = false; // 结束流式传输} else {// 逐字追加内容this.messages[this.messages.length - 1].content += data.content;this.$nextTick(() => {this.scrollToBottom();});}});// 监听 WebSocket 关闭this.socket.onClose(() => {console.log('WebSocket 连接已关闭');});},// 发送消息sendMessage() {if (this.userInput.trim() && !this.isStreaming) {this.addUserMessage(this.userInput); // 显示用户输入的消息this.isStreaming = true;// 通过 WebSocket 发送消息this.socket.send({data: JSON.stringify({message: this.userInput}),success: () => {console.log('消息发送成功');this.addBotMessage(''); // 初始化一个空消息用于逐步填充},fail: (err) => {console.error('消息发送失败:', err);}});this.userInput = ''; // 清空输入框}},// 添加用户消息addUserMessage(content) {this.messages.push({from: 'user',content: content});},// 添加机器人回复addBotMessage(content) {this.messages.push({from: 'bot',content: content});},// 滚动到底部scrollToBottom() {const query = uni.createSelectorQuery().in(this);query.select('.chat-box').boundingClientRect(res => {if (res) {uni.pageScrollTo({scrollTop: res.height,duration: 0});}}).exec();}}};
</script><style scoped>/* 页面容器 */.container {background-color: #fff;height: 100%;/* padding: 0 15px; *//* 加入左右边距 */}/* 顶部导航栏 */.navbar {background-color: #ff65a3;color: #fff;text-align: center;padding: 12px 0;font-size: 18px;font-weight: bold;}/* 聊天框 */.chat-box {padding: 10px;margin-bottom: 70px;/* 留出输入框的空间 */padding-left: 0;margin: 0 15px;width: auto;/* 去掉左边距,给消息更多空间 */padding-right: 0;/* 去掉右边距 */}/* 聊天消息 */.chat-item {margin: 10px 0;display: flex;}.user-message {text-align: right;background-color: #ff65a3;color: #fff;padding: 10px;border-radius: 10px;max-width: 80%;margin-left: auto;}.bot-message {text-align: left;background-color: #f2f2f2;color: #000;padding: 10px;border-radius: 10px;max-width: 80%;margin-right: auto;}/* 输入框 */.input-area {display: flex;position: fixed;bottom: 0;left: 0;width: 93%;padding: 10px;background-color: #fff;border-top: 1px solid #ddd;padding-left: 15px;/* 左边距 */padding-right: 15px;/* 右边距 */}.input-box {flex: 1;height: 40px;border-radius: 20px;border: 1px solid #ddd;padding: 0 15px;font-size: 16px;}.send-btn {background-color: #ff65a3;color: #fff;font-size: 16px;border: none;padding: 0 20px;border-radius: 20px;margin-left: 10px;}/* 恋爱指导标签 */.guidance-tags {display: flex;overflow-x: scroll;white-space: nowrap;padding: 10px;background-color: #ffe5f1;}.tag-item {display: inline-block;background-color: #ff65a3;color: white;padding: 8px 15px;margin-right: 10px;border-radius: 20px;font-size: 14px;cursor: pointer;}
</style>
相关文章:
uniapp+node+mysql接入deepseek实现流式输出
node import express from express; import mysql from mysql2; import cors from cors; import bodyParser from body-parser; import axios from axios; import { WebSocketServer } from ws; // 正确导入 WebSocketServerconst app express();// Middlewares app.use(cors…...
PHP MySQL 创建数据库
PHP MySQL 创建数据库 引言 在网站开发中,数据库是存储和管理数据的核心部分。PHP 和 MySQL 是最常用的网页开发语言和数据库管理系统之一。本文将详细介绍如何在 PHP 中使用 MySQL 创建数据库,并对其操作进行详细讲解。 前提条件 在开始创建数据库之…...
UE4 World, Level, LevelStreaming从入门到深入
前言 在《塞尔达传说:旷野之息》中,玩家攀上初始高塔的瞬间,目光所及的山川湖泊皆可抵达;在《艾尔登法环》中,黄金树的辉光始终悬于地平线之上,指引玩家穿越无缝衔接的史诗战场。这些现代游戏杰作背后的核…...
3月8日实验
拓扑: 需求: 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到白度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分,PC1可以正常访问3.3.3.0/24网段,但是PC2不允许 3.学校内部路由使用静态路由&#…...
IO多路复用实现并发服务器
一.select函数 select 的调用注意事项 在使用 select 函数时,需要注意以下几个关键点: 1. 参数的修改与拷贝 readfds 等参数是结果参数 : select 函数会直接修改传入的 fd_set(如 readfds、writefds 和 exceptfds…...
【漫话机器学习系列】122.相关系数(Correlation Coefficient)
深入理解相关系数(Correlation Coefficient) 1. 引言 在数据分析、统计学和机器学习领域,研究变量之间的关系是至关重要的任务。我们常常想知道:当一个变量变化时,另一个变量是否也会随之变化?如果会&…...
控制系统分类
文章目录 定义与特点1. 自治系统(Autonomous System)与非自治系统(Non-Autonomous System)自治系统非自治系统 2. 线性系统(Linear System)与非线性系统(Nonlinear System)线性系统非…...
文档操作方法得合理使用
博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…...
Python asyncIO 面试题及参考答案 草
目录 如何正确定义一个协程函数?直接调用协程会引发什么问题? 使用 async def 定义的协程与普通函数执行流程有何本质区别? 解释 asyncio.run () 的作用及与手动管理事件循环的差异 为什么协程中必须使用 await 而非 yield 挂起操作? 写出通过 async for 实现异步迭代器…...
计算机网络——交换机
一、什么是交换机? 交换机(Switch)是局域网(LAN)中的核心设备,负责在 数据链路层(OSI第二层)高效转发数据帧。它像一位“智能交通警察”,根据设备的 MAC地址 精准引导数…...
matlab和FPGA联合仿真时读写.txt文件数据的方法
在FPGA开发过程中,往往需要将MATLAB生成的数据作为原始激励灌入FPGA进行仿真。为了验证FPGA计算是否正确,又需要将FPGA计算结果导入MATLAB绘图与MATLAB计算结果对比。 下面是MATLAB“写.txt”、“读.txt”,Verilog“读.txt”、“写.txt”的代…...
解锁DeepSpeek-R1大模型微调:从训练到部署,打造定制化AI会话系统
目录 1. 前言 2.大模型微调概念简述 2.1. 按学习范式分类 2.2. 按参数更新范围分类 2.3. 大模型微调框架简介 3. DeepSpeek R1大模型微调实战 3.1.LLaMA-Factory基础环境安装 3.1大模型下载 3.2. 大模型训练 3.3. 大模型部署 3.4. 微调大模型融合基于SpirngBootVue2…...
【分布式】聊聊分布式id实现方案和生产经验
对于分布式Id来说,在面试过程中也是高频面试题,所以主要针对分布式id实现方案进行详细分析下。 应用场景 对于无论是单机还是分布式系统来说,对于很多场景需要全局唯一ID, 数据库id唯一性日志traceId 可以方便找到日志链&#…...
uniapp或者vue 使用serialport
参考https://blog.csdn.net/ykee126/article/details/90440499 版本是第一位:否则容易编译失败 node 版本 18.14.0 npm 版本 9.3.1 electron 版本 30.0.8 electron-rebuild 版本 3.2.9 serialport 版本 10.0.0 需要python环境 main.js // Modules to control app…...
机器学习12-视觉识别任务
机器学习12-视觉识别任务 分类语义分割滑动窗口滑动窗口的实现思路优点缺点现代替代方法 全卷积(Fully Convolutional Networks, FCN)FCN 的工作原理FCN 的性能优势FCN 的应用案例FCN 的局限性改进方向下采样可学习的上采样:转置卷积 目标检测区域建议Se…...
使用paramiko爆破ssh登录
一.确认是否存在目标主机是否存在root用户 重跑 CVE-2018-15473用户名枚举漏洞 检测: import paramiko from paramiko.ssh_exception import AuthenticationExceptiondef check_user(username, hostname, port):ssh paramiko.SSHClient()ssh.set_missing_host_key…...
游戏引擎学习第146天
音高变化使得对齐读取变得不可能,我们可以支持循环声音了。 我们今天的目标是完成之前一段时间所做的音频代码。这个项目并不依赖任何引擎或库,而是一个教育项目,目的是展示从头到尾运行一个游戏所需要的全部代码。无论你对什么方面感兴趣&a…...
装饰器模式--RequestWrapper、请求流request无法被重复读取
目录 前言一、场景二、原因分析三、解决四、更多 前言 曾经遇见这么一段代码,能看出来是把request又重新包装了一下,核心信息都不会改变 后面了解到这叫 装饰器模式(Decorator Pattern) :也称为包装模式(Wrapper Pat…...
【算法题】小鱼的航程
问题: 分析 分析题目,可以看出,给你一个开始的星期,再给一个总共天数,在这些天内,只有周六周日休息,其他全要游泳250公里。 那分支处理好啦 当星期为6时,需要消耗2天,…...
视频录像机视频通道是指什么
视频录像机的视频通道是指摄像机在监控矩阵或硬盘录像机设备上的视频输入的物理位置。 与摄像头数量关系:在视频监控系统中,有多少个摄像头就需要多少路视频通道,通道数量决定了视频录像机可接入摄像头的数量,一般硬盘录像机有4路…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
