简体   繁体   English

使用flask web-app监控实时数据流

[英]Monitoring a real-time data stream with a flask web-app

This is based on the answer posted at https://stackoverflow.com/a/13388915/819544 这是基于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? 也许不是threading我需要使用多处理? 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. “正在启动webapp ...”消息永远不会打印,也不会显示正常的消息,并且访问提供的URL会确认应用程序未运行。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM