Python (flask+;socket.IO)发出回调的结果是我的REST端点的响应

Python (flask+;socket.IO)发出回调的结果是我的REST端点的响应,python,flask,socket.io,flask-socketio,Python,Flask,Socket.io,Flask Socketio,我是node.JS的开发人员,但我正在从事一个需要使用Flask框架与Python一起工作的项目 问题是,当客户端请求rest flask应用程序的端点时,我需要使用socket.IO发出一个事件,并从套接字服务器获取一些数据,然后这些数据就是端点的响应。但是我不知道如何发送这个,因为flask需要一个“return”语句来说明响应是什么,而我的回调是在另一个上下文中进行的 我尝试做的示例:(有一些评论解释) 导入socketio 导入事件 从烧瓶进口烧瓶,请求 sio=socketio.Ser

我是node.JS的开发人员,但我正在从事一个需要使用Flask框架与Python一起工作的项目

问题是,当客户端请求rest flask应用程序的端点时,我需要使用socket.IO发出一个事件,并从套接字服务器获取一些数据,然后这些数据就是端点的响应。但是我不知道如何发送这个,因为flask需要一个“return”语句来说明响应是什么,而我的回调是在另一个上下文中进行的

我尝试做的示例:(有一些评论解释)

导入socketio
导入事件
从烧瓶进口烧瓶,请求
sio=socketio.Server()
app=烧瓶(名称)
@应用程序路径(“/test/”)
def get(参数):
def确认(数据):
打印(数据)#应为响应
sio.emit('event',param,callback=ack)#套接字服务器调用我的ack函数
#如果没有return语句,端点将返回500
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=socketio.Middleware(sio,app)
eventlet.wsgi.server(eventlet.listen(“”,8000)),应用程序)

也许,这里正确的问题是:这可能吗?我将给你一种方法来实现你特别想要的,但我相信你在这方面有一个重要的设计缺陷,正如我在上面的评论中解释的那样。按照这种编码方式,您的
socketio.Server()
对象将广播到所有客户端,因此无法获得回调。如果希望向一个客户机发出(希望不是发送HTTP请求的客户机),则需要向发出中添加
room=client_sid
参数。或者,如果您正在联系Socket.IO服务器,则需要在此处使用Socket.IO客户端,而不是服务器

在任何情况下,要在调用回调函数之前阻止HTTP路由,可以使用
事件
对象。大概是这样的:

from threading import Event
from flask import jsonify

@app.route('/test/<param>')
def get(param):
    ev = threading.Event()
    result = None

    def ack(data):
        nonlocal result
        nonlocal ev

        result = {'data': data}
        ev.set()  # unblock HTTP route

    sio.emit('event', param, room=some_client_sid, callback=ack)
    ev.wait()  # blocks until ev.set() is called
    return jsonify(result)
从线程导入事件
从flask导入jsonify
@应用程序路径(“/test/”)
def get(参数):
ev=线程。事件()
结果=无
def确认(数据):
非局部结果
非局部电动汽车
结果={'data':数据}
ev.set()#取消阻止HTTP路由
sio.emit('event',param,room=some_client_sid,callback=ack)
ev.wait()#阻塞,直到调用ev.set()
返回jsonify(结果)

为什么不返回一个空字符串和一个200?因为我需要返回在SoCKE.IO服务器上执行的回调(不是客户端)上接收到的参数,这不是你的主要问题,但是考虑到如果你想发射到SoCKE.IO服务器(不是你的客户机),那么你必须在这里使用SoCKI.IO客户端。服务器无法与另一台服务器通信。ev.wait()正在阻止我的应用程序,因此回调函数上的代码未被执行。是否有一种简单的方法可以将flask更改为非阻塞工作?是否对eventlet的标准库进行了修补?
from threading import Event
from flask import jsonify

@app.route('/test/<param>')
def get(param):
    ev = threading.Event()
    result = None

    def ack(data):
        nonlocal result
        nonlocal ev

        result = {'data': data}
        ev.set()  # unblock HTTP route

    sio.emit('event', param, room=some_client_sid, callback=ack)
    ev.wait()  # blocks until ev.set() is called
    return jsonify(result)