使用烧瓶web-app监控实时数据流 [英] Monitoring a real-time data stream with a flask web-app

查看:219
本文介绍了使用烧瓶web-app监控实时数据流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是基于 https://stackoverflow.com/a/13388915/819544 发布的答案。 p>

我想要监视一个数据流并将其推送到类似于上面的答案的前端,但流应用程序尽快开始生成/监视数据的位置开始,客户端总是看到数据流的当前状态(无论他们是否从服务器请求数据,它们都会持续运行)。

我很确定我需要通过线程将数据流从前端分离出来,但是我不太熟悉线程/异步编程,并且相信我做错了。也许而不是线程我需要使用多处理?这里大概是我想要做的(从上面链接的答案修改):

app.py

 #!/ usr / bin / env python $ b $ from __future__ import division 
import itertools
进口时间
从烧瓶进口烧瓶,响应,重定向,请求,url_for
从随机进口gauss
进口线程
$ b $ app =烧瓶(__ name__)

#生成流数据并从中计算统计数据
class MyStreamMonitor(object):
def __init __(self):
self.sum = 0
self.count = 0
@property
def mu(self):
try:
outv = self.sum / self.count
除外:
outv = 0
return outv
def generate_values(self):
while True:
time.sleep(.1)#一个人工延迟
yield gauss(0,1)
def monitor(self,report_interval = 1):
print正在启动数据流m ...
for self.generate_values():
self.sum + = x
self.count + = 1

stream = MyStreamMonitor( )

@ app.route('/')
def index():
if request.headers.get('accept')=='text / event-stream ':
def事件():
而真:
产生data:%s%d \\\
\\\
%(stream.count,stream.mu)
time.sleep(.01)#人工延迟。只要价值更新,宁愿推。
返回Response(events(),content_type ='text / event-stream')
返回重定向(url_for('static',filename ='index.html'))

if __name__ ==__main__:
#数据监视器应该在应用程序启动后立即启动。
t = threading.Thread(target = stream.monitor())
t.start()
print正在启动webapp ...#我们从来没有到过这个地步。
app.run(host ='localhost',port = 23423)

static / index.html

 <!doctype html> 
< title>伺服器发送活动演示< / title>
< style>
#data {
text-align:center;
}
< / style>
< script src =http://code.jquery.com/jquery-latest.js>< / script>
< script>
if(!! window.EventSource){
var source = new EventSource('/');
source.onmessage = function(e){
$(#data)。text(e.data);
}
}
< / script>
< div id =data>尚未收到任何内容< / div>

此代码无效。 正在启动webapp ...消息不会打印,也不会执行常规烧瓶消息,并访问提供的URL确认应用程序未运行。

如何让数据监视器在后台运行,以便烧瓶可以访问所看到的值并将当前状态推送给客户端甚至:只要客户端正在监听,当相关的值改变时,推送当前的状态)?

解决方案

我只需要改变这一行

  t = threading.Thread(target = stream.monitor())
  t =线程 
$ b>

.Thread(target = stream.monitor)


This is based on the answer posted at https://stackoverflow.com/a/13388915/819544

I would like to monitor a stream of data and push it to a front-end similar to the answer above, but where the stream starts generating/monitoring data as soon as the app kicks off, and the client always sees the current state of the data steam (which keeps running whether or not they are requesting data from the server).

I'm pretty sure I need to separate the data stream from the front-end via threading, but I'm not very practiced with threaded/asynchronous programming and believe I'm doing it wrong. Maybe instead of threading I need to be using multiprocessing? Here's roughly what I'm trying to do (modified from the answer linked above):

app.py

#!/usr/bin/env python
from __future__ import division
import itertools
import time
from flask import Flask, Response, redirect, request, url_for
from random import gauss
import threading

app = Flask(__name__)

# Generate streaming data and calculate statistics from it
class MyStreamMonitor(object):
    def __init__(self):
        self.sum   = 0
        self.count = 0
    @property
    def mu(self):
        try:
            outv = self.sum/self.count
        except:
            outv = 0
        return outv
    def generate_values(self):
        while True:
            time.sleep(.1)  # an artificial delay
            yield gauss(0,1)
    def monitor(self, report_interval=1):
        print "Starting data stream..."
        for x in self.generate_values():
            self.sum   += x
            self.count += 1 

stream = MyStreamMonitor()

@app.route('/')
def index():
    if request.headers.get('accept') == 'text/event-stream':
        def events():
            while True:
                yield "data: %s %d\n\n" % (stream.count, stream.mu)
                time.sleep(.01) # artificial delay. would rather push whenever values are updated. 
        return Response(events(), content_type='text/event-stream')
    return redirect(url_for('static', filename='index.html'))

if __name__ == "__main__":
    # Data monitor should start as soon as the app is started.
    t = threading.Thread(target=stream.monitor() )
    t.start()
    print "Starting webapp..." # we never get to this point.
    app.run(host='localhost', port=23423)

static/index.html

<!doctype html>
<title>Server Send Events Demo</title>
<style>
  #data {
    text-align: center;
  }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
if (!!window.EventSource) {
  var source = new EventSource('/');
  source.onmessage = function(e) {
    $("#data").text(e.data);
  }
}
</script>
<div id="data">nothing received yet</div>

This code doesn't work. The "Starting webapp..." message never prints, nor do the normal flask messages, and visiting the served URL confirms the app isn't running.

How do I get the data monitor to run in the background in such a way that flask can access the values it's seeing and push the current state up to the client (better even: as long as the client is listening, push the current state when the relevant values change)?

解决方案

I just needed to change this line

t = threading.Thread(target=stream.monitor())

to this:

t = threading.Thread(target=stream.monitor)

这篇关于使用烧瓶web-app监控实时数据流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆