如何将文本数据流式传输(产生)到Pythonywhere上的flask应用程序的jinja2模板
我尝试在我的Pythonanywhere帐户上实现“流式内容” 它或多或少地与上面显示的内容类似: 比照 除此之外,我的视图正在计算一个复杂的过程,可能需要一分钟的时间,并将其数据生成到我的模板,其中脚本应该更新一些进度条(“source.onmessage”) 这在我的开发机器上非常有效,但在我的pythonywhere帐户上却不行。在这台服务器上,进程看起来很拥挤(进度条永远不会更新,除非在最后,进度从0%增长到100%),尽管一切都进展顺利,例如我的如何将文本数据流式传输(产生)到Pythonywhere上的flask应用程序的jinja2模板,flask,wsgi,pythonanywhere,Flask,Wsgi,Pythonanywhere,我尝试在我的Pythonanywhere帐户上实现“流式内容” 它或多或少地与上面显示的内容类似: 比照 除此之外,我的视图正在计算一个复杂的过程,可能需要一分钟的时间,并将其数据生成到我的模板,其中脚本应该更新一些进度条(“source.onmessage”) 这在我的开发机器上非常有效,但在我的pythonywhere帐户上却不行。在这台服务器上,进程看起来很拥挤(进度条永远不会更新,除非在最后,进度从0%增长到100%),尽管一切都进展顺利,例如我的print语句正确地呈现在我的服务器日志
print
语句正确地呈现在我的服务器日志中)
在上面引用的片段中,有一个注释:
不过请注意,一些WSGI中间件可能会中断流媒体,所以请注意
在调试环境中使用分析器和其他东西时要小心
您可能已经启用了
这可能是问题所在吗?会有解决办法吗
来自我的jinja2模板的JS代码:
<script type="text/javascript">
/* progress bar */
var source = new EventSource("{{ url_for('BP.run', mylongprocess_id=mylongprocess_id) }}");
source.onmessage = function(event) {
console.log(event.data);
var data = event.data.split("!!");
var nodeid = data[0];
var process = data[1];
var process_status = data[2];
var postpro = data[3];
var postpro_status = data[4];
$('.pb1').css('width', process+'%').attr('aria-valuenow', process);
$('.pb2').css('width', postpro+'%').attr('aria-valuenow', process);
document.getElementById("process_status").innerHTML = process_status;
document.getElementById("postpro_status").innerHTML = postpro_status;
document.getElementById("nodeid").innerHTML = nodeid;
if (postpro >= 100) {
setTimeout(function() {
console.log("progress is finished!");
document.getElementById("status").innerHTML = "redirecting to {{url_for('.view_sonix_result', mylongprocess_id=mylongprocess_id)}}";
window.location.replace("{{url_for('.terminate_analysis', mylongprocess_id=mylongprocess_id)}}");
}, 2); // / setTimeout function
} // /if
else {
document.getElementById("status").innerHTML = "pending...";
} // /else
} // /function
</script>
/*进度条*/
var source=neweventsource(“{url_for('BP.run',mylongprocess_id=mylongprocess_id)}”);
source.onmessage=函数(事件){
console.log(事件数据);
var data=event.data.split(“!!”);
var nodeid=数据[0];
var过程=数据[1];
var过程_状态=数据[2];
var postpro=数据[3];
var postpro_状态=数据[4];
$('.pb1').css('width',process+'%').attr('aria-valuenow',process);
$('.pb2').css('width',postro+'%').attr('aria-valuenow',process);
document.getElementById(“进程状态”).innerHTML=进程状态;
document.getElementById(“postpro_状态”).innerHTML=postpro_状态;
document.getElementById(“nodeid”).innerHTML=nodeid;
如果(postro>=100){
setTimeout(函数(){
log(“进度已完成!”);
document.getElementById(“status”).innerHTML=“重定向到{{url\'u for('.view\'u sonix\'u result',mylongprocess\'u id=mylongprocess\'u id)}}”;
replace({{url_for('.terminate_analysis',mylongprocess_id=mylongprocess_id)}});
},2);///setTimeout函数
}///如果
否则{
document.getElementById(“status”).innerHTML=“待定…”;
}///其他
}///函数
我的(简化)视图:
@BP.route(“/run/”)
@需要登录
def运行(mylongprocess_id):
mylongprocess=mylongprocess.query.get\u或\u 404(mylongprocess\u id)
project=project.query.get\u或\u 404(mylongprocess.project\u id)
检查权限(当前用户、项目“用户”、404)
A、 lcs=_创建_分析(MyLong流程)
@复制\u当前\u请求\u上下文
def gen(MyLong进程、节点ID、存储路径):
打印('正在运行%s“%A”)
对于A.runiterator(lcs)中的(loopnb、total_循环、pct、lclabel):
打印('ran%d/%d(%.1f%%)“%s”'%(loopnb,total_循环,
pct,LCT(标签)
进度=('数据:%s!!%f!!%s!!%f!!%s\n\n'%
(节点ID、pct、lclabel、0,“正在等待…”)
产量进度
打印('正在对%s“%A”进行后处理)
postpro=加载节点(存储路径,节点id=节点id)
对于postpro.\u builditer(target='web'中的步骤、总计、pct、操作,
buildfile=None):
进度=('数据:%s!!%f!!%s!!%f!!%s\n\n'%
(节点ID,100,‘正常’,pct,动作。替换(“”,“”)
产量进度
打印('正在终止%s“%A”)
_终止分析(A,MyLong流程)
返回响应(gen(mylongprocess,mylongprocess.nodeid),mimetype='text/event stream')
当您的流量托管在Pythonywhere上时,它将通过nginx代理,nginx缓冲响应,除非另有规定
为了让一切都顺利进行
response.headers['X-Accel-Buffering']='no'
'\n'
,因为python也会缓冲到行尾@BP.route('/run/<int:mylongprocess_id>')
@login_required
def run(mylongprocess_id):
mylongprocess = mylongprocess.query.get_or_404(mylongprocess_id)
project = Project.query.get_or_404(mylongprocess.project_id)
check_rights(current_user, project, 'user', 404)
A, lcs = _create_analysis(mylongprocess)
@copy_current_request_context
def gen(mylongprocess, nodeid, store_path):
print('now runing %s' % A)
for (loopnb, total_loops, pct, lclabel) in A.runiterator(lcs):
print('ran %d/%d (%.1f%%) "%s"' % (loopnb, total_loops,
pct, lclabel))
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, pct, lclabel, 0, 'waiting...'))
yield progress
print('now postprocessing %s' % A)
postpro = load_node(store_path, node_id=nodeid)
for step, total, pct, action in postpro._builditer(target='web',
buildfile=None):
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, 100, 'ok', pct, action.replace('_', ' ')))
yield progress
print('now terminating %s' % A)
_terminate_analysis(A, mylongprocess)
return Response(gen(mylongprocess, mylongprocess.nodeid), mimetype='text/event-stream')