Flask-SocketIO与Connexion兼容吗?Django对接实时进度实现咨询
嘿,这个需求我之前帮朋友处理过类似的,给你梳理下可行的方案~
一、先给你吃定心丸:Flask-SocketIO 完全能和 Connexion 搭配使用
Connexion本质是基于Flask构建的API框架,所以两者的集成非常顺畅,核心就是把Connexion封装的Flask实例和SocketIO绑定起来就行。下面是具体的实现步骤:
后端(Connexion + Flask-SocketIO)实现
- 先装依赖:
pip install connexion flask-socketio eventlet
(eventlet是SocketIO推荐的异步服务器,能避免请求阻塞)
- 初始化应用并绑定SocketIO:
import connexion from flask_socketio import SocketIO, emit import uuid import time # 创建Connexion应用,加载你的API定义文件 app = connexion.FlaskApp(__name__, specification_dir='./') app.add_api('swagger.yaml') # 关键:获取Connexion内部的Flask实例,绑定SocketIO socketio = SocketIO(app.app, cors_allowed_origins="*") # 跨域根据你的实际情况调整 # 定义后台任务,处理耗时操作并推送进度 def process_task(task_id): # 第一步:推送「创建中」状态 socketio.emit( 'task_progress', {'task_id': task_id, 'status': '创建中'}, namespace='/progress' ) time.sleep(2) # 模拟耗时操作 # 第二步:推送「处理中」状态 socketio.emit( 'task_progress', {'task_id': task_id, 'status': '处理中'}, namespace='/progress' ) time.sleep(2) # 第三步:推送「完成」状态 socketio.emit( 'task_progress', {'task_id': task_id, 'status': '完成'}, namespace='/progress' ) # 你的API提交端点,触发后台任务 def submit_task(): task_id = str(uuid.uuid4()) # 生成唯一任务ID,用于前端对应监听 # 用SocketIO的后台任务启动处理逻辑,避免阻塞API请求 socketio.start_background_task(target=process_task, task_id=task_id) return {'task_id': task_id}, 202 # 记得把submit_task绑定到你的swagger路由上
前端(Django)实现
在Django模板里引入SocketIO客户端,编写监听逻辑:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> <script> // 连接到后端SocketIO服务,指定命名空间 const socket = io('http://你的后端域名/progress'); // 表单提交逻辑 document.getElementById('submit-form').addEventListener('submit', function(e) { e.preventDefault(); // 发送POST请求到Connexion API fetch('http://你的后端域名/submit-task', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(/* 你的表单数据 */) }) .then(res => res.json()) .then(data => { const taskId = data.task_id; // 监听对应任务的进度推送 socket.on('task_progress', function(progress) { if (progress.task_id === taskId) { // 更新页面上的状态文本 document.getElementById('status-text').textContent = progress.status; // 任务完成后移除监听 if (progress.status === '完成') { socket.off('task_progress'); } } }); }); }); </script> <div id="status-text">等待提交...</div> <form id="submit-form"> <!-- 你的表单元素 --> <button type="submit">提交</button> </form>
二、替代方案:Server-Sent Events(SSE)
如果你的场景只是后端单向向前端推送进度,不需要双向通信(比如用户不用中途取消任务),SSE会更轻量——不需要额外的SocketIO依赖,浏览器原生支持。
后端(Connexion)实现
from flask import Response, stream_with_context import uuid import time def generate_progress_stream(task_id): def stream(): yield f"data: {{'task_id': '{task_id}', 'status': '创建中'}}\n\n" time.sleep(2) yield f"data: {{'task_id': '{task_id}', 'status': '处理中'}}\n\n" time.sleep(2) yield f"data: {{'task_id': '{task_id}', 'status': '完成'}}\n\n" return Response(stream_with_context(stream()), mimetype='text/event-stream') # 提交任务端点 def submit_task(): task_id = str(uuid.uuid4()) return { 'task_id': task_id, 'progress_url': f'/progress/{task_id}' }, 202 # 进度流端点 def get_task_progress(task_id): return generate_progress_stream(task_id)
前端(Django)实现
<script> document.getElementById('submit-form').addEventListener('submit', function(e) { e.preventDefault(); fetch('http://你的后端域名/submit-task', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(/* 表单数据 */) }) .then(res => res.json()) .then(data => { // 创建SSE连接 const eventSource = new EventSource(data.progress_url); // 监听进度推送 eventSource.onmessage = function(event) { const progress = JSON.parse(event.data); document.getElementById('status-text').textContent = progress.status; // 完成后关闭连接 if (progress.status === '完成') { eventSource.close(); } }; // 处理连接错误 eventSource.onerror = function() { eventSource.close(); document.getElementById('status-text').textContent = '请求出错'; }; }); }); </script> <div id="status-text">等待提交...</div> <form id="submit-form"> <!-- 你的表单元素 --> <button type="submit">提交</button> </form>
最后总结
- 如果需要双向通信(比如用户中途取消任务),选Flask-SocketIO + Connexion的方案,集成毫无问题;
- 如果只是单向进度推送,SSE更轻量,无需额外依赖。
内容的提问来源于stack exchange,提问作者iaskaboutanything
相关产品推荐
相关产品推荐

