我正在寻找一个运行网络服务器,该服务器读取sys.stdin
上的流。该读取需要连续发生,例如在while循环中。
但是,我还希望运行一个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
循环作为后台进程运行,以释放烧瓶路由侦听器?任何建议都会有所帮助!
答案 0 :(得分:0)
您可以尝试在线程中运行它
import threading
x = threading.Thread(target=thread_function, args=(index,))
threads.append(x)
x.start()
对于线程函数,在其中定义您的while循环
答案 1 :(得分:0)
尝试调查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()
答案 2 :(得分:0)
我最终做了以下事情:
我有一个小文件publisher.py
,它在while循环中从给定主机上的端口读取(尽管也可以使用上面的代码从sys.stdin中读取)。当它组成frame
时,会将其发布到redis数据存储中。
然后,在我的Flask路由侦听器/frame
内,我只对redis数据存储执行ping操作,然后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)