Как я могу отправить широковещательное сообщение всем клиентам из другого класса с помощью socektio, Flask - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь отправить общее широковещательное сообщение всем клиентам при изменении файлов в файловой системе.

Что работает:

  • трансляция общего сообщения работает нормально.

    socketio.emit('refresh_request', "A broadcasted message received by all clients", callback=messageReceived, broadcast=True)

  • получение уведомлений об изменениях файловой системы с помощью библиотеки watchdog в консоли.

    тип события: измененный путь : C: \ appFilesToMonitor \ afile_Copy.py

Проблема :

Я должен отправить широковещательное сообщение изнутри обработчик файлового монитора. Если я выполняю socketio.emit () в этом классе, я получаю сообщение об ошибке в консоли:

Файл "C: \ Tools \ Programming \ Python37-32 \ lib \ site- packages \ flask \ globals.py ", строка 38, в _lookup_req_object повысить RuntimeError (_request_ctx_err_msg) RuntimeError: Работа вне контекста запроса.

Обычно это означает, что вы пытались использовать функциональность, для которой требовался активный 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()
        ...

Вопрос:

Как я могу отправить широковещательное сообщение всем клиентам из другого класса. (в этом случае: если файл изменяется в файловой системе)

Ответы [ 2 ]

0 голосов
/ 21 января 2020

создать экземпляр SocketIO с:

socketio = SocketIO(app, async_mode='threading')

(кредит Flask, Python и Socket.io: многопоточное приложение дает мне «RuntimeError: работа вне контекста запроса» , Никлас Р комментирует ответ Бертона)

и испускает с:

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)


Все работает сейчас.

0 голосов
/ 20 января 2020

Эта ошибка возникает при попытке доступа к переменным контекста Flask, обычно эта ошибка возникает в фоновых задачах, но вы можете использовать Flask Контекст вне конечной точки, используя:

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