项目需求📠
后端能够持续不断地将特定数据传输给前端,这些数据可能包括当前任务进度、实时聊天信息、点赞或评论等互动通知。
今天主要的目标就是如何实现数据间的传输
技术栈🪁
我想到的办法就是通过websocket协议实现这一操作
后端:python-flask
前端:uniapp-vue-js
错误案例❌
首先我在网络上找到了这么一个方案,先上代码给大家看一下
不要复制,是错的
不要复制,是错的
不要复制,是错的
错误代码
后端部分
from flask import Flask from flask_socketio import SocketIO, emit import time app = Flask(__name__) app.config['SECRET_KEY'] = 'your_secret_key' socketio = SocketIO(app, cors_allowed_origins="*") @socketio.on('start_task') def handle_start_task(): # 模拟一个长时间运行的任务 for i in range(1, 101): time.sleep(0.1) # 假设每个步骤需要0.1秒 # 发送进度更新到客户端 emit('progress', {'progress': i}, broadcast=False) if __name__ == '__main__': socketio.run(app, debug=True, host='0.0.0.0', port=5000)
前端代码
export default { data() { return { socket: null, progress: 0 }; }, methods: { connectSocket() { this.socket = uni.connectSocket({ url: 'ws://你的服务器地址:5000/', success: () => { console.log('WebSocket连接成功'); // 可以选择在这里发送'start_task'事件来启动任务 this.sendStartTask(); }, fail: (err) => { console.error('WebSocket连接失败:', err); } }); // 监听WebSocket接收到的消息 uni.onSocketMessage((res) => { if (res.data.includes('progress')) { // 解析消息内容,这里假设服务器发送的是JSON字符串 const data = JSON.parse(res.data); if (data.progress) { this.progress = data.progress; console.log('Progress update:', this.progress); // 可以在这里更新UI或执行其他逻辑 } } }); // 监听WebSocket连接关闭 uni.onSocketClose(() => { console.log('WebSocket连接已关闭'); }); }, sendStartTask() { if (this.socket.readyState === 1) { // WebSocket连接已打开 this.socket.send(JSON.stringify({ event: 'start_task' })); } else { console.log('WebSocket连接未打开'); } } }, mounted() { this.connectSocket(); } };
问题分析
再说一遍上面的代码有问题,不要复制
上面的代码问题实在是太多,我暂时就不一一讲了,先讲一下为什么这段代码改都没办法改,还有要是一意孤行,会看到什么问题
按上面这样弄会看到什么
这段报错的意思是,没有
@app.route('/')
就是根路径的执行函数,那我给它加上去不就完了
那么你会看到
这个意思是前端传回一条不可解析的数据
为什么会这样
一开始问题出在后端,按我刚刚说的加上去就行了
后面问题出在前端
前端上传的数据不能被后端的flask socketio访问到
查了很多资料才知道
原来这玩意跟torch一样,也有版本对应问题
现在flask socketio的版本基本上都是5.x,这里面就涉及到一个问题,前端的程序(架构里内置的apiuniapp,线上测试网页)很多都是之前做的,或者之前封装的,版本不匹配,所以发到后端的东西,后端不认识
正确的解决方案😎
只要老老实实自己手动安装Javascript socketio的最新版的了,如何用最原始的api来运行
下载和导入
命令行 cd 进入项目文件夹
然后
npm install socket.io-client
这个下的就是 Javascript socketio的最新版
然后再通过
import io from 'socket.io-client'
在uniapp文件中导入
解决代码
放一下真正有用的代码,这个可以直接复制
后端
from threading import Lockfrom flask import Flaskfrom flask_socketio import SocketIO, emitimport timeapp = Flask(__name__)app.config['SECRET_KEY'] = 'secret!'socketio = SocketIO(app,cors_allowed_origins = '*')@socketio.on('start_task')def handle_start_task(data): # 模拟一个长时间运行的任务 for i in range(1, 101): time.sleep(0.1) # 假设每个步骤需要0.1秒 # 发送进度更新到客户端 emit('message', {'progress': i}, broadcast=False) # broadcast=False 表示不广播给所有连接的客户端if __name__ == '__main__': socketio.run(app, debug=True, host='0.0.0.0', port=5000)
在终端输入 flask run 运行
前端
<template> <view> <!-- 你的页面内容 --> </view></template><script> // 引入socket.io-client import io from 'socket.io-client'; export default { data() { return { socket: null, }; }, created() { // 连接到Socket.IO服务器,这是本地地址,改成你服务器的地址也行 this.socket = io('http://127.0.0.1:5000'); // 监听连接事件 this.socket.on('connect', () => { console.log('连接成功'); //连接成功向后端发送一个事件"start_task",{}里面是携带的数据 this.socket.emit('start_task', { detail: 'Please start the task now!' }); }); // 监听事件 //这里的事件名要和后端发过来的事件名对应,如后端发了一个名为"message"的事件 //这里得填"message" this.socket.on('message', (data) => { console.log('收到消息:', data); }); // 监听断开连接事件 this.socket.on('disconnect', () => { console.log('连接断开'); }); }, beforeDestroy() { // 组件页面销毁前断开连接 if (this.socket) { this.socket.disconnect(); } }, };</script>
代码讲解📐
简单的讲解一下代码
只要是为了防踩坑,没讲的不是特别重要,想知道为什么的可以自己用AI查一下
socketio = SocketIO(app,cors_allowed_origins = '*')
cors_allowed_origins = '*',用来解决跨域问题,要不然会400
@socketio.on('start_task')
监听事件"start_task"
emit('message', {'progress': i}, broadcast=False)
发送一个名为"message"的事件,{}里面是传递出去的数据,broadcast=False表示只向触发者发送,要向所有人发送改为True就行了
前端的解释,我就在注释中写了,有不懂欢迎留言
PS:回复很快