Python 如何使用socektio,Flask从另一个类中向所有客户端发送广播消息

Python 如何使用socektio,Flask从另一个类中向所有客户端发送广播消息,python,flask,socket.io,flask-socketio,watchdog,Python,Flask,Socket.io,Flask Socketio,Watchdog,当文件系统中的文件发生更改时,我试图向所有客户端发送一条通用广播消息 什么有效: 广播一般信息效果良好 socketio.emit('refresh\u request',“所有客户端接收的广播消息”,callback=messageReceived,broadcast=True) 使用控制台中的watchdog库获取中文件系统更改的通知 事件类型:修改的路径:C:\appFilesToMonitor\afile\u Copy.py 问题: 我必须从文件监视器处理程序中发送广播消息。如果我

当文件系统中的文件发生更改时,我试图向所有客户端发送一条通用广播消息

什么有效:

  • 广播一般信息效果良好

    socketio.emit('refresh\u request',“所有客户端接收的广播消息”,callback=messageReceived,broadcast=True)

  • 使用控制台中的watchdog库获取中文件系统更改的通知

    事件类型:修改的路径:C:\appFilesToMonitor\afile\u Copy.py

问题

我必须从文件监视器处理程序中发送广播消息。如果我在这个类中执行socketio.emit(),我会在控制台中收到一条错误消息:

文件“C:\Tools\Programming\Python37-32\lib\site packages\flask\globals.py”,第38行,在\u lookup\u req\u对象中 引发运行时错误(\u请求\u ctx\u错误\u消息) 运行时错误:在请求上下文之外工作

这通常意味着您试图使用所需的功能 活动的HTTP请求。请参阅有关测试的文档 有关如何避免此问题的信息

我认为我必须以某种方式向类提供socketio对象。我尝试了一个回调函数,并尝试传递socketio对象。但是没有用。我的灵感已经耗尽了,很明显我还不明白什么

课程的相关部分:

如果需要更多,请告诉我

app = Flask(__name__)
socketio = SocketIO(app)

def file_change_broadcast_callback(msg):
    app.logger.warning("*********testing broadcast************")
    socketio.emit('refresh_request', msg, callback=messageReceived, broadcast=True)

class MyHandler(FileSystemEventHandler):
    def __init__(self, sio, callback_function):
        self.sio = sio
        self.callback_function = callback_function

    def on_modified(self, event):
        print(f'--------------------------file change event type: {event.event_type}  path : {event.src_path}')

        # not working
        # emit_arguments = {"status": "refresh_request", "msg":"yooo de mannen"}
        # socketio.emit('refresh_request', emit_arguments, callback=messageReceived, broadcast=True)

        # not working (nothing received by clients)  (error: RuntimeError: Working outside of request context.)
        # self.sio.emit('refresh_request', "msg", callback=messageReceived, broadcast=True)

        # not working (error: RuntimeError: Working outside of request context.)
        # self.callback_function("The filesystem has been changed.")


if __name__ == "__main__":
        ...
        event_handler = MyHandler(socketio,file_change_broadcast_callback)
        observer = Observer()
        observer.schedule(event_handler, path=str(Path( app.config['webapp']['base_folder'])), recursive=True)
        observer.start()
        ...

问题:


如何从另一个类中向所有客户端发送广播消息。(在本例中:如果文件系统中的文件发生更改)

当您尝试访问上下文烧瓶变量时,会发生此错误,通常此错误发生在后台任务中,但您可以使用端点之外的烧瓶上下文,方法是:

with app.test_request_context():
   socketio.emit('refresh_request', msg, callback=messageReceived, broadcast=True)

使用以下内容创建SocketIO实例:

socketio = SocketIO(app, async_mode='threading')
(感谢Niklas R对伯顿回答的评论)

并发射:

class MyHandler(FileSystemEventHandler):
    def __init__(self):
        pass
    def on_modified(self, event):
        print(f'--------------------------file change event type: {event.event_type}  path : {event.src_path}')
        socketio.emit('refresh_request', "files changed warning.", broadcast=True)



现在一切正常。

谢谢Caio,我试过了,但问题是Watchdog使用了不同的线程。