我有一个算法,等待将近5秒钟来生成响应,我想在发送请求后立即向用户发送一个ack(http 200),告诉他已收到他的请求并等待5秒钟。
生成器功能:
def chunked_res():
yield "Chunk 1"
stop = time.time() + 5 # wait for 5 seconds
while time.time() < stop:
pass
yield "Chunk 2"
在某些观点中:
response = HttpResponse ( chunked_res() )
response['Connection'] = 'close'
response['Transfer-Encoding'] = 'chunked'
response['status'] = 200
return response
浏览器响应:
“Transfer-Encoding:chunked \ nstatus:200 \ nConnection:close \ nContent-Type:text / html; charset = utf-8 \ n \ nChunk 1Chunk 2”
问题: 我得到了必要的响应(Chunk 1,Chunk 2),但是在5秒之后。我想首先发送“Chunk 1”然后在5秒后发送“Chunk 2”(更新respose)。是否有任何特定的设置/更改来实现此功能?
更新
Django = 1.4 python = 2.7
答案 0 :(得分:2)
他们刚刚在django 1.5中添加了StreamingHttpResponse,在早期版本中添加了passing an iterator(&lt; = 1.4),您可以流式传输(或“chunk”)数据。
def chunked_res():
yield "Chunk 1"
time.sleep(5) # wait for 5 seconds
yield "Chunk 2"
def myview(request):
g = chunked_res()
return HttpResponse(g)
答案 1 :(得分:2)
你真的想避免这样做......
stop = time.time() + 5 # wait for 5 seconds
while time.time() < stop:
pass
这将导致您的进程的CPU使用率在5秒内达到100%,这对于Web应用程序来说是一个巨大的数额。在共享托管环境中,您可能会从托管服务提供商那里收到一封讨厌的电子邮件,如果您有自己的服务器,那么您在循环中占用的那些周期可以有效地部署在处理其他请求中。这样做:
time.sleep(5)
这将使线程(或进程)休眠5秒钟,然后内核可以自由安排其他任务,或者在没有其他事情要做的情况下休眠CPU(节省电力和冷却成本)。 p>
答案 2 :(得分:0)
实际上,解决方案是使浏览器的第一个块大小至少为1024个字符,以便逐步显示。
How to stream an HttpResponse with Django
def chunked_res():
yield "Chunk 1"
yield " " * 1024 # Encourage browser to render incrementally (either 1024 or 1024-7{length of "chunk 1"} = 1017)
time.sleep(5) # wait for 5 seconds
yield "Chunk 2"
def myview(request):
g = chunked_res()
return HttpResponse(g)
如果您使用 nginx ,则必须设置 proxy_buffering = off,以便服务器在1024数据块准备就绪时刷新响应。 http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size
适用于: HTTP / 1.0和HTTP / 1.1
答案 3 :(得分:0)
请澄清其他答案:对于Django 1.5+,您必须使用StreamingHttpResponse。常规的HttpResponse将收集完整的响应,并在完成后才返回。
from django.http import StreamingHttpResponse
def chunked_res():
yield "Chunk 1"
yield " " * 1024 # Encourage server to begin transferring and browser to begin rendering
time.sleep(5) # wait for 5 seconds
yield "Chunk 2"
def myview(request):
return StreamingHttpResponse(chunked_res())