[英]Flask: Server-sent event (SSE) stream function is halted when processing input
[英]Background thread logging to a Server Sent Event stream in a Flask app
我正在嘗試構建一個Flask應用程序,該應用程序在后台運行一些任務。 此任務(工作人員)使用標准的logging
模塊記錄正在發生的事情。 我想使用Server Sent Events將日志消息直接推送到Web瀏覽器,但是我無法通過gevent
廣播gevent
。
在以下代碼段中,該工作器已正確啟動,應調用SSEHandler.emit
方法,但在執行gevent.spawn
之后似乎未執行notify
函數。
import gevent
from gevent.wsgi import WSGIServer
from gevent.queue import Queue
from flask import Flask, Response
import time
import logging
import threading
from worker import Worker
class SSEHandler(logging.Handler):
def __init__(self):
logging.Handler.__init__(self)
self.subscriptions = []
def emit(self, record):
try:
msg = self.format(record)
print "sending", msg
def notify(subs, msg):
print "broadcasting!"
for sub in subs[:]:
sub.put(msg)
gevent.spawn(notify, self.subscriptions, msg)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
def subscribe(self):
print "subscribed"
q = Queue()
self.subscriptions.append(q)
try:
while True:
result = q.get()
yield "data: %s\n\n"%result
except GeneratorExit: # Or maybe use flask signals
subscriptions.remove(q)
app = Flask(__name__)
handler = SSEHandler()
handler.setLevel(logging.DEBUG)
worker = None
# Client code consumes like this.
@app.route("/")
def index():
debug_template = """
<html>
<head>
</head>
<body>
<h1>Server sent events</h1>
<div id="event"></div>
<script type="text/javascript">
var eventOutputContainer = document.getElementById("event");
var evtSrc = new EventSource("/subscribe");
evtSrc.onmessage = function(e) {
console.log(e.data);
eventOutputContainer.innerHTML = e.data;
};
</script>
</body>
</html>
"""
return(debug_template)
@app.route("/subscribe")
def subscribe():
return Response(handler.subscribe(), mimetype="text/event-stream")
@app.route("/start")
def start():
def run():
global worker
global handler
worker = Worker(handler)
worker.go()
threading.Thread(target=run).start()
return "Going"
if __name__ == "__main__":
app.debug = True
server = WSGIServer(("", 5000), app)
server.serve_forever()
import logging
import time
class Worker:
def __init__(self, handler):
self.log = logging.getLogger('sselog.worker.Worker')
self.log.setLevel(logging.DEBUG)
self.log.addHandler(handler)
self.log.info("Initialized")
def go(self):
i = 0
while True:
time.sleep(1)
self.log.info("I'm working so hard %u", i)
i+=1
好吧,問題是我使用普通線程和睡眠而不是gevent東西。 對其進行更改和/或應用猴子補丁后,一切都將正常運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.