在我的基于烧瓶的http服务器设计用于远程管理RPI上的一些服务我接近了一个我无法单独解决的问题,因此请求你给我一个提示。
概念: 通过flask和gevent我可以停止并运行在RPI上运行的一些(两个)服务。我使用gevent和服务器端事件来尊重javascript以便收听html更新。
html页面显示服务的状态(开/关/处理),并提供打开/关闭它们的按钮。另外显示一些系统参数(CPU,RAM,HDD,NET)。
只要打开一个用户/页面,一切都可以正常工作。只要有更多用户访问烧瓶服务器,就会在每个用户/页面之间进行一次竞赛,并且不会重新加载所有页面。
问题: 如何向所有正在运行的greenlets sse_worker()发送消息并在常规作业之上处理它?</ p>
高级代码下方。完整的源代码可以在这里找到:https://github.com/petervflocke/flasksse_rpi检查sse.py文件
def sse_worker(): #neverending task
while True:
if there_is_a_change_in_process_status:
reload_page=True
else:
reload_page=False
Do some other tasks:
update some_single_parameters_to_be_passed_to_html_page
yield 'data: ' + json.dumps(all_parameters)
gevent.sleep(1)
@app.route('/stream/', methods=['GET', 'POST'])
def stream():
return Response(sse_worker(), mimetype="text/event-stream")
if __name__ == "__main__":
gevent.signal(signal.SIGTERM, stop)
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
...在html页面上,相应地处理流式json数据。如果服务状态已根据reload_page变量更改,则javascript会重新加载完整页面 - 代码提取如下:
<script>
function listen() {
var source = new EventSource("/stream/");
var target1 = document.getElementById("time");
....
source.onmessage = function(msg) {
obj = JSON.parse(msg.data);
target1.innerHTML = obj.time;
....
if (obj.reload == "1") {
location.reload();
}
}
}
listen();
</script>
我想要的解决方案是扩展sse_worker(),如下所示:
def sse_worker():
while True:
if there_is_a_change_in_process_status:
reload_page=True
# NEW: set up a semaphore/flag that there is a change on the page
message_set(reload)
elif message_get(block=false)==reload: # NEW: check the semaphore
# issue: the message_get must retun "reload" for _all_ active sse_workers, that all of them can push the reload to "their" pages
reload_page=True
else:
reload_page=False
Do some other tasks:
update some_single_parameters_to_be_passed_to_html_page
yield 'data: ' + json.dumps(all_parameters)
gevent.sleep(1)
我希望我可以传递我的信息。在你身边有什么想法可以解决同步问题吗?请注意,我们在同一个sse_worker函数中有生产者和消费者。
非常欢迎任何想法! 最好的祝福 彼得