RuntimeError:在请求上下文之外工作 [英] RuntimeError: working outside of request context

查看:609
本文介绍了RuntimeError:在请求上下文之外工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个'keepalive'websocket线程,一旦有人连接到页面,每10秒发送一次到浏览器,但得到一个错误,不知道如何绕过它。任何想法如何使这项工作。而且,如果发送断开连接,我将如何杀死这个线程?

谢谢!

  @ socketio.on('connect',namespace ='/ endpoint')
def test_connect():
emit('my response',{'data':'< ())
$ b def background_thread():
如何发送服务端生成的事件给客户端的例子。
count = 0
而真:
time.sleep(10)
count + = 1
emit('my response',{'data':'websocket is live '},namespace ='/ endpoint')

全局线程
如果线程为None:
thread = Thread(target = background_thread)
thread.start()


解决方案

要知道谁是客户,因为你正在发送一个直接的消息。为此,后台线程需要访问请求上下文。在Flask中,您可以使用 copy_current_request_context 装饰器在线程中安装当前请求上下文的副本:

  @copy_current_request_context 
def background_thread():
如何将服务器生成的事件发送到客户端的示例。
count = 0
而真:
time.sleep(10)
count + = 1
emit('my response',{'data':'websocket is alive alive'},namespace ='/ endpoint ')

一对笔记:


  • 默认情况下, emit 调用不会在设置命名空间时返回给客户端。客户端。当您在请求上下文之外广播或发送消息时,需要指定名称空间。
  • 请注意,您的设计需要为每个连接的客户端分别设置一个线程。拥有一个广播给所有客户端的单个后台线程会更高效。请参阅我在Github存储库上提供的示例应用程序: https://github.com/miguelgrinberg / Flask-SocketIO / tree / master / example


在客户端断开连接时停止线程,可以使用任何多线程线程机制让线程知道它需要退出。例如,这可以是您在断开事件中设置的全局变量。一个不太好的替代方案很容易实现,当客户端离开并使用它退出线程时,等待发出来引发异常。


I am trying to create a 'keepalive' websocket thread to send an emit every 10 seconds to the browser once someone connects to the page but getting an error and not sure how to get around it. Any idea how to make this work. And how would i kill this thread once a 'disconnect' is sent?

Thanks!

@socketio.on('connect', namespace='/endpoint')
def test_connect():
    emit('my response', {'data': '<br>Client thinks i\'m connected'})

    def background_thread():
        """Example of how to send server generated events to clients."""
        count = 0
        while True:
            time.sleep(10)
            count += 1
            emit('my response', {'data': 'websocket is keeping alive'}, namespace='/endpoint')

    global thread
    if thread is None:
        thread = Thread(target=background_thread)
        thread.start()

解决方案

You wrote your background thread in a way that requires it to know who's the client, since you are sending a direct message to it. For that reason the background thread needs to have access to the request context. In Flask you can install a copy of the current request context in a thread using the copy_current_request_context decorator:

@copy_current_request_context
def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        time.sleep(10)
        count += 1
        emit('my response', {'data': 'websocket is keeping alive'}, namespace='/endpoint')

Couple of notes:

  • It is not necessary to set the namespace when you are sending back to the client, by default the emit call will be on the same namespace used by the client. The namespace needs to be specified when you broadcast or send messages outside of a request context.
  • Keep in mind your design will require a separate thread for each client that connects. It would be more efficient to have a single background thread that broadcasts to all clients. See the example application that I have on the Github repository for an example: https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example

To stop the thread when the client disconnects you can use any multi-threading mechanism to let the thread know it needs to exit. This can be, for example, a global variable that you set on the disconnect event. A not so great alternative that is easy to implement is to wait for the emit to raise an exception when the client went away and use that to exit the thread.

这篇关于RuntimeError:在请求上下文之外工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆