簡體   English   中英

在Flask應用程序中運行while循環作為后台進程

[英]Run while loop as background process in Flask app

我正在尋找運行在sys.stdin上讀取流的Web服務器。 這種閱讀需要不斷發生,例如在一個循環中。

但是,我還希望運行一個Flask服務器來偵聽對/data請求,並將從sys.stdin讀取的最后一位數據發送到請求代理。

到目前為止,我發現我的while循環正在暫停我的應用程序的執行,這是絕對有意義的。 這是我的設置:

from flask import Flask, jsonify
import sys

# state
frames = []
frame = []

while True:
  l = sys.stdin.readline()
  if 'end_frame' in l:
    frames = [frame] + frames
    frame = []
  elif l.rstrip('\n'):
    frame.append(l.rstrip('\n'))

# app
app = Flask(__name__, static_url_path='')

@app.route('/frames')
def get_frames():
  return jsonify(frames)

app.run(host='0.0.0.0', port=5050)

有沒有辦法將while循環作為后台進程運行,以便釋放燒瓶路由偵聽器? 任何的意見都將會有幫助!

您可以嘗試在線程中運行它

import threading
x = threading.Thread(target=thread_function, args=(index,))
threads.append(x)
x.start()

對於線程函數,在其中定義while循環

嘗試查看類似BackgroundScheduler的內容。 它在后台運行任務作為單獨的線程,而不會停止燒瓶監聽器。

from apscheduler.schedulers.background import BackgroundScheduler
...
...
def readlines():
  l = sys.stdin.readline()
  if 'end_frame' in l:
    frames = [frame] + frames
    frame = []
  elif l.rstrip('\n'):
    frame.append(l.rstrip('\n'))

with app.app_context():
    scheduler = BackgroundScheduler()
    scheduler.add_job(readlines, 'interval', seconds=10)
    scheduler.start()

我最后做了以下事情:

我有一個小文件publisher.py ,它在一個while循環中從給定主機上的一個端口讀取(盡管它也可以使用上面的代碼從sys.stdin中讀取)。 當它組成一個frame ,它會將該幀發布到redis數據存儲區。

然后,在我的Flask路由偵聽器/frame ,我只是ping redis數據存儲,然后jsonify結果。 通過這種方式,我的發布者和服務器一起工作,為客戶提供數據......

publisher.py

import sys, socket, redis, json

# config
stream = {'host': '127.0.0.1', 'port': 6000} # streaming data host / port
r = redis.Redis(host='127.0.0.1', port=6379) # redis instance host / port

# consume data from a host+port and publish to redis on localhost
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((socket.gethostbyname(stream['host']), stream['port'])) # host, port

# consume data
frame = [] # initialize the container obj that will hold all frame data
while True:
  data = client.recv(1024).decode('utf8')
  for l in data.split('\n'):
    if 'end_frame' in l:
      d = {i.split(':')[0]: i.split(':')[1] for i in frame if ':' in i}
      r.set('frame', json.dumps(d))
      frame = []
      print(' * published frame', d.get('frame_number', ''))
    elif l.rstrip('\n'):
      frame.append(l.rstrip('\n'))

server.py

from flask import Flask, jsonify
import redis, sys, os, json

# app
app = Flask(__name__, static_url_path='')

# redis
r = redis.Redis(host='127.0.0.1', port=6379) # redis instance host / port

# route listeners
@app.route('/api/frame')
def get_frame():
  frame = json.loads(r.get('frame').decode('utf8'))
  return jsonify(frame)

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=5050)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM