我发现 Miguel Grinberg 的工作非常鼓舞人心,因此我选择在一个大学项目中使用 Flask 和 FlaskSocketIO 库来制作一些 Java 工具(相当复杂的东西,但出于好奇,我正在研究这个项目)。
基本上,python 部分只是创建一个命令,在后台线程中执行它并将每个日志推送到屏幕,这要归功于这个伟大的 Flask SocketIO 库。
所描述的所有内容都很好,但是当我想通过第二次调用相同的 URL 来重新启动任务时遇到问题,我收到了这个错误,我没有找到任何线程,所以我认为它是微不足道的或非常讨厌的(但是中间什么都没有!)。有人有想法吗?
File "/Library/Python/2.7/site-packages/eventlet/wsgi.py", line 485, in handle_one_response
write(b'')
File "/Library/Python/2.7/site-packages/eventlet/wsgi.py", line 380, in write
raise AssertionError("write() before start_response()")
AssertionError: write() before start_response()
而且,当然,这是我的代码(灵感来自 Miguel 的示例,因为我无法自己设置它......)
#!/usr/bin/env python
async_mode = None
if async_mode is None:
try:
import eventlet
async_mode = 'eventlet'
except ImportError:
pass
if async_mode is None:
try:
from gevent import monkey
async_mode = 'gevent'
except ImportError:
pass
if async_mode is None:
async_mode = 'threading'
print('async_mode is ' + async_mode)
# monkey patching is necessary because this application uses a background
# thread
if async_mode == 'eventlet':
import eventlet
eventlet.monkey_patch()
elif async_mode == 'gevent':
from gevent import monkey
monkey.patch_all()
import time
from threading import Thread
import subprocess
from os import chdir
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import InstrumentationScripts as IS
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None
def background_thread():
time.sleep(1)
socketio.emit('my response',
{'data': "Thread Started", 'count': 0},
namespace='/test')
cb = IS.CommandBuilder()
args = cb.createCommand().split()
chdir(cb.InstrumentationPepDirectory)
process = subprocess.Popen(args, stdout=subprocess.PIPE)
for out in iter(process.stdout.readline, b""):
out = '<pre>' + out + '</pre>'
socketio.emit('my response', {'data': out, 'count':0}, namespace='/test')
time.sleep(0.001)
socketio.emit('my response',
{'data': "Thread Finished", 'count': 0},
namespace='/test')
@app.route('/')
def index():
global thread
if thread is None:
thread = Thread(target=background_thread)
thread.daemon = True
thread.start()
return render_template('index.html')
@socketio.on('connect', namespace='/test')
def test_connect():
emit('my response', {'data': 'Connected', 'count': 0})
if __name__ == '__main__':
socketio.run(app)
如果你需要完整的代码,这里是repo