Flask, Python and Socket.io: multithreading app is giving me "RuntimeError: working outside of request context"

Flask, Python and Socket.io: multithreading app is giving me "RuntimeError: working outside of request context"

我一直在使用 FlaskPythonFlask-[=39 开发应用程序=]图书馆。我遇到的问题是,由于某些上下文问题

,以下代码将无法正确执行 emit
RuntimeError: working outside of request context

我现在只为整个程序编写一个 python 文件。这是我的代码 (test.py):

from threading import Thread
from flask import Flask, render_template, session, request, jsonify, current_app, copy_current_request_context
from flask.ext.socketio import *

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

def somefunction():
    # some tasks
    someotherfunction()

def someotherfunction():
    # some other tasks
    emit('anEvent', jsondata, namespace='/test') # here occurs the error

@socketio.on('connect', namespace='/test')
def setupconnect():
    global someThread
    someThread = Thread(target=somefunction)
    someThread.daemon = True

if __name__ == '__main__':
    socketio.run(app)

在 StackExchange 中,我一直在阅读一些解决方案,但它们没有用。我不知道我做错了什么。

我试过在 emit:

之前添加一个 with app.app_context():
def someotherfunction():
    # some other tasks
    with app.app_context():
        emit('anEvent', jsondata, namespace='/test') # same error here

我尝试的另一个解决方案是在 someotherfunction() 之前添加装饰器 copy_current_request_context 但它说装饰器必须在本地范围内。我把它放在 someotherfunction() 里面,第一行,但同样的错误。

如果有人能帮助我,我会很高兴。提前致谢。

您的错误是 'working outside of request context'。您试图通过推送应用程序上下文来解决它。相反,您应该推送请求上下文。请参阅 http://kronosapiens.github.io/blog/2014/08/14/understanding-contexts-in-flask.html

上关于 contexts in flask 的解释

您的 somefunction() 中的代码可能使用了请求上下文中的全局对象(如果我不得不猜测您可能使用了请求对象)。当您的代码未在新线程内执行时,它可能会起作用。但是当您在新线程中执行它时,您的函数不再在原始请求上下文中执行,并且它不再具有访问请求上下文特定对象的权限。所以你必须手动推动它。

所以你的函数应该是

def someotherfunction():
    with app.test_request_context('/'):
        emit('anEvent', jsondata, namespace='/test')

您在这里使用了错误的 emit。您必须使用您创建的 socketio 对象的发射。所以而不是

emit('anEvent', jsondata, namespace='/test') # here occurs the error 采用: socketio.emit('anEvent', jsondata, namespace='/test') # here occurs the error