Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.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 运行时错误:在请求上下文之外工作_Python_Websocket_Flask_Flask Socketio - Fatal编程技术网

Python 运行时错误:在请求上下文之外工作

Python 运行时错误:在请求上下文之外工作,python,websocket,flask,flask-socketio,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

我正在尝试创建一个“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()
@socketio.on('connect',namespace='/endpoint')
def测试_连接():
emit('my response',{'data':'
客户端认为我已连接') def background_thread(): “”“如何将服务器生成的事件发送到客户端的示例。”“” 计数=0 尽管如此: 时间。睡眠(10) 计数+=1 emit('my response',{'data':'websocket保持活动状态'},名称空间='/endpoint') 全局线程 如果线程为“无”: 线程=线程(目标=背景线程) thread.start()
您编写后台线程的方式要求它知道谁是客户,因为您正在向它发送直接消息。因此,后台线程需要访问请求上下文。在Flask中,您可以使用
copy\u current\u request\u 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')
几点注意:

  • 发送回客户机时不必设置名称空间,默认情况下,
    emit
    调用将位于客户机使用的相同名称空间上。在请求上下文之外广播或发送消息时,需要指定命名空间
  • 请记住,您的设计将需要为每个连接的客户端提供一个单独的线程。如果有一个向所有客户机广播的后台线程,效率会更高。有关示例,请参见我在Github存储库上的示例应用程序:

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

这并不是回答问题,而是您可能希望从前端处理该问题。在浏览器中的on_connect回调中,设置一个setInterval以每10000毫秒发出一声“ping”,然后让后端响应一声“pong”。它将使您免于无数小时的调试线程和内存泄漏。(但作为旁注,socket.io已经为您完成了这项工作)