加上charset utf-8有效果了,我用的是 chrome,根本还是应该做成长连接吧
On Monday, October 15, 2012 12:53:00 PM UTC+8, agentzh wrote:
Hello!2012/10/14 level077:
> 我有个脚本要执行比较长时间,比如30秒,脚本是会持续输出的,但是通过浏览器访问会一直等到socket timeout。
> 使用ngx.flush()还是会等到socket timeout。
> 怎么用才能达到跟直接执行脚本一样的效果?
>
由于你没有提供具体的 nginx 配置和 Lua 代码,所以我不能帮你诊断具体的问题所在。
下面我且给出一个在我本地测试通过的完整实例:
location = /t {
default_type text/html;
charset utf-8;
content_by_lua '
ngx.say("<html><body>")
for i = 1, 100 do
ngx.say("i = ", i, "<br>")
ngx.flush()
ngx.sleep(1)
end
ngx.say("</body></html>")
';
}
在这个例子中,我每隔 1 秒输出一行 HTML 行,一共连续输出 100 行。整个响应会持续 100 秒的时间。
在我本机分别通过 curl 7.24.0、Mozilla Firefox 16.0.1 以及 Google Chrome
22.0.1229.94 中访问 http://localhost:8080/t (假设 nginx 监听的是本地的 8080
端口)的时候,都会看到类似命令行脚本输出那样一秒输出一行的动态刷新的效果。
不过,这里有几个问题需要特别注意的:
1. 至少在 Firefox 和 Chrome 中需要显式指定字符编码,注意上例中使用的 charset utf-8 配置,这样
Content-Type 响应头中会加上 charset=utf-8 属性。如果你未显式指定属性,则它们会等到接收了 1KB
以上的数据才开始实际渲染接受到的响应数据(至少对于 Firefox 是这样的)。
2. Chrome 貌似并不会对 text/plain 类型的响应进行增量渲染,而 Firefox 是可以的。所以上例我显式配置了
text/html 这个 default_type.
3. 在相邻的两次输出之间不能隔太久,否则 HTTP 客户端仍会超时。比如在上例中,我在相邻两次输出之间设置了 1 秒的延时。
4. 调用 ngx.flush() 属于高代价操作,上例中每输出不到 10
字节就调用一次,在真实世界里过于昂贵了(但便于这里演示效果)。一般还是在输出较大的数据块(比如 1KB、4KB 或者更多)之后按需调用。
我手头并没有现成的 IE 浏览器,欢迎你(以及其他朋友)反馈 IE 中对于上例的实测结果 :)
Best regards,
-agentzh