python - 运行时错误 : working outside of request context

标签 python websocket flask flask-socketio

我正在尝试创建一个“keepalive”websocket 线程,以便在有人连接到该页面后每 10 秒向浏览器发送一个 emit,但我遇到了一个错误,我不确定如何解决它。

关于如何使这项工作有任何想法吗?

一旦发送“断开连接”,我将如何终止该线程?

谢谢!

@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()

最佳答案

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

@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')

注意事项:

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

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

关于python - 运行时错误 : working outside of request context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27220194/

相关文章:

python - 谷歌 Colab GPU Tensorflow 1.x

python - 即使文件存在,文件 b'train.csv' 也不存在

c# - 将 REST Web API 应用程序与 SignalR 集成?

node.js - 为什么安装 bufferUtil 和 utf-8-validate 可以显着提高 Node.js 中 WS websocket 库的性能?

flask - 在 jinja2 模板中转义 jinja2 语法

python - 确定汇率的算法

python - 使用 Pulp 更新约束

javascript - Nodejs "ws"Websocket 服务器

python - WTForm "OR"条件验证器? (电子邮件或电话)

flask - Flask HTTP header 接口(interface)是否对获取和设置都不区分大小写?