Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 烧瓶+;RabbitMQ+;SocketIO-转发消息_Python_Flask_Socket.io_Rabbitmq - Fatal编程技术网

Python 烧瓶+;RabbitMQ+;SocketIO-转发消息

Python 烧瓶+;RabbitMQ+;SocketIO-转发消息,python,flask,socket.io,rabbitmq,Python,Flask,Socket.io,Rabbitmq,我在通过SocketIO从RabbitMQ向用户发送消息时遇到了问题 我有一份申请。 当前的用户流看起来像 问题是我无法设置RabbitMQ侦听器,该侦听器通过SocketIO将消息转发到浏览器。每次我都会犯不同的错误。主要是连接已关闭,或者我正在应用程序上下文之外工作 我尝试了很多方法,这里是我的最后一个 # callback def mq_listen(uid): rabbit = RabbitMQ() def cb(ch, method, properties, body

我在通过SocketIO从RabbitMQ向用户发送消息时遇到了问题

我有一份申请。 当前的用户流看起来像

问题是我无法设置RabbitMQ侦听器,该侦听器通过SocketIO将消息转发到浏览器。每次我都会犯不同的错误。主要是连接已关闭,或者我正在应用程序上下文之外工作

我尝试了很多方法,这里是我的最后一个

# callback 
def mq_listen(uid):
    rabbit = RabbitMQ()
    def cb(ch, method, properties, body, mq=rabbit):
        to_return = [0]  # mutable
        message = Message.load(body)
        to_return[0] = message.get_message()

        emit('report_part', {"data": to_return[0]})

    rabbit.listen('results', callback=cb, id=uid)

# this is the page, which user reach
@blueprint.route('/report_result/<uid>', methods=['GET'])
def report_result(uid):

    thread = threading.Thread(target=mq_listen, args=(uid,))
    thread.start()

     return render_template("property/report_result.html", socket_id=uid)
导致

RuntimeError: working outside of request context
我将很乐意为您提供任何使用技巧或示例


非常感谢

错误消息表明这是烧瓶问题。在处理请求时,Flask会设置一个上下文,但因为您使用的是线程,所以该上下文会丢失。当需要时,它不再可用,因此Flask给出了“在请求上下文之外工作”错误

解决此问题的一种常见方法是手动提供上下文。文档中有一节介绍了这一点:


您的代码没有显示socketio部分。但我想知道使用类似flask socketio的东西是否可以简化一些东西。。。(). 我会在后台打开RabbitMQ连接(最好是一次),并使用
emit
函数向连接的SocketIO客户端发送任何更新。

我遇到了类似的问题,在一天结束时,这是因为当您发出请求时,flask会将请求上下文传递给客户端。但解决方案不是使用app.app_context()添加。这就是hackey,并且肯定会有错误,因为您不是以本机方式发送请求上下文

我的解决方案是创建一个重定向,以便保持请求上下文,如下所示:

def sendToRedisFeed(eventPerson, type):
    eventPerson['type'] = type
    requests.get('http://localhost:5012/zmq-redirect', json=eventPerson)
这是我的重定向函数,所以每当有一个事件我想推送到我的PubSub,它就会通过这个函数,然后推送到localhost端点

from flask_sse import sse

app.register_blueprint(sse, url_prefix='/stream')

@app.route('/zmq-redirect', methods=['GET'])
def send_message():
    try:
        sse.publish(request.get_json(), type='greeting')
        return Response('Sent!', mimetype="text/event-stream")

    except Exception as e:
        print (e)
        pass
现在,无论何时将事件推送到my/zmq重定向端点,它都会通过SSE重定向和发布

最后,总结一下,客户:

var source = new EventSource("/stream");

source.addEventListener(
  "greeting",
  function(event) {
    console.log(event)
  }
)

对于您所包含的内容,我没有直接的答案(尽管图很好),但我以前遇到过“请求上下文之外”的问题,这通常是一个问题:(1)尝试使用flask API之外的函数调用flask,这意味着必须将flask部分从函数中排除,或者(2)一种回调,需要使用从flask中提取的数据进行设置,以便在稍后启动回调时需要flask,或者(3)一些其他调用链丢弃了flask上下文,并且无法传递所需的数据。但我不确定这是否有帮助-/我在您的示例中没有看到,但您是否创建了应用程序上下文?在请求之外运行时,需要推送上下文。
var source = new EventSource("/stream");

source.addEventListener(
  "greeting",
  function(event) {
    console.log(event)
  }
)