如何从SocketIO回调获取返回值作为Flask请求的响应?
解决Flask请求获取SocketIO回调返回值的问题
你的问题核心在于:Flask视图是同步执行流程,但SocketIO的emit回调是异步触发的——你调用emit后立刻返回了它的返回值(本身就是None),此时回调函数还未执行,自然拿不到目标数据。
要解决这个问题,需要用同步阻塞的方式等待回调执行完成,拿到结果后再返回给Flask请求。可以借助threading.Event实现同步逻辑:
修改后的完整代码
from flask import Flask, request, jsonify from flask_socketio import SocketIO from threading import Event app = Flask(__name__) socketio = SocketIO(app, cors_allowed_origins="*") clients = [] # 假设这是你维护的已连接客户端列表 @app.route("/api/<token>") def recharge(token): socket_connected_user_index = next((i for i, x in enumerate(clients) if x["name"] == token), None) if socket_connected_user_index is not None: socket_id = clients[socket_connected_user_index]['id'] number = request.args['number'] amount = request.args['amount'] pin = request.args['pin'] api_key = token recharge_data = dict(number=number, amount=amount, pin=pin, api_key=api_key) # 初始化结果存储容器和同步事件 result_container = [None] callback_event = Event() def server_callback(data): print('server call back >> ', data) # 将回调结果存入容器(用列表是因为可变对象可跨线程修改) result_container[0] = data # 触发事件,通知主线程可以继续执行 callback_event.set() return data # 发送SocketIO请求事件 socketio.emit('recharge_request', {'data': recharge_data}, to=socket_id, callback=server_callback) # 阻塞等待回调执行完成,设置10秒超时避免请求挂死 callback_event.wait(timeout=10) # 根据结果返回响应 if result_container[0] is not None: return jsonify(result_container[0]) else: return jsonify({"status": "Timeout waiting for SocketIO response"}) else: return jsonify({"status":"User not connected"})
关键逻辑说明
- 结果容器:用列表
result_container存储回调结果,因为Python中可变对象的内部修改可以跨线程被感知,普通不可变变量做不到这一点。 - 同步事件:
callback_event.wait()会阻塞当前Flask请求线程,直到回调函数调用callback_event.set()或者超时,确保主线程能拿到回调结果后再返回响应。 - 超时处理:添加超时逻辑可以避免因为SocketIO客户端无响应,导致Flask请求一直处于阻塞状态。
内容的提问来源于stack exchange,提问作者Darshil Lakhani
相关产品推荐
相关产品推荐

