Мне интересно, как можно решить следующую проблему лучше, в текущем состоянии, в котором я сейчас нахожусь.
Я предлагаю следующую архитектуру:
Архитектура
Идея состоит в том, чтобы использовать многопоточность для этой задачи, запустив Flask Socket.IO в потоке и сделав цикл while в другом потоке, который может отправлять запросы по требованию всем подключенным клиентам.
Проект
- main.py
- analyze.py
- webapp.py
analyze.py
Реальная программа будет извлекать данные из файла каждые несколько секунд, и если что-то будет изменено, она проанализирует его содержимое и результат будет передан через Socket.IO всем клиентам.
import webapp
def analyze():
while True:
message_object = analyzeStuff()
webapp.send_message(message_object)
webapp.py
Здесь мы реализуем фактические конечные точки Flask Socket.IO. Для простоты, вот небольшой снимок того, что происходит на моей стороне:
from flask import Flask
from flask_socketio import SocketIO
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
socket = SocketIO(app)
@socket.on('connect')
def test_connect():
print('Client connected')
pass
@socket.on('disconnect')
def test_disconnect():
print('Client disconnected')
pass
def send_message(data):
socket.emit('message', data)
# print('sending message "{}".'.format(data))
main.py
В основном потоке мы открываем поток Socket.IO, затем запускаем анализ.
Я использую eventlet.monkey_patch()
(хотя я не уверен, что именно он делает), чтобы иметь возможность вызывать .emit
из другого потока, чем тот, на котором установлен сервер Socket.IO.
import analyze
import webapp
import threading
import eventlet
eventlet.monkey_patch()
if __name__ == '__main__':
# Start the server
webapp_thread = threading.Thread(target=run_web_app)
webapp_thread.start()
# Run the Analyze loop
analyze.analyze()
Текущее состояние работает нормально, хотя в настоящее время у меня возникают некоторые проблемы при установке этого на сервер apache2 wsgi-mode, над которым я сейчас работаю.
Несмотря на это, это выглядит ужасно, и я не могу перестать думать, что должен быть лучший способ сделать это. Есть предложения?