【学习笔记】使用flask 制作websocket协议连接,实现服务器多次向前端发送数据
烟花节 2024-08-25 08:33:02 阅读 83
项目需求📠
后端能够持续不断地将特定数据传输给前端,这些数据可能包括当前任务进度、实时聊天信息、点赞或评论等互动通知。
今天主要的目标就是如何实现数据间的传输
技术栈🪁
我想到的办法就是通过websocket协议实现这一操作
后端:python-flask
前端:uniapp-vue-js
错误案例❌
首先我在网络上找到了这么一个方案,先上代码给大家看一下
不要复制,是错的
不要复制,是错的
不要复制,是错的
错误代码
后端部分
<code>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="*") code>
@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)code>
前端代码
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文件中导入
解决代码
放一下真正有用的代码,这个可以直接复制
后端
<code>from threading import Lock
from flask import Flask
from flask_socketio import SocketIO, emit
import time
app = 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)code>
在终端输入 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:回复很快
最后留一个运行结果😉
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。