这是我为解决问题而设置的一个简单的 Rails 4 项目:
https://github.com/rejacobson/rails4-streamtest https://github.com/rejacobson/rails4-streamtest
我在 /home/stream 设置了一条路由,应该以 1 秒的间隔传输一行文本 5 次。
def stream
5.times do |n|
puts "Streaming: #{n}"
response.stream.write "Streaming: #{n+1}"
sleep 1
end
rescue IOError => e
puts 'Connection closed'
ensure
response.stream.close
end
当我使用 tcp:// 运行 puma 时,没有 nginx,流媒体工作完美。
curl -N http://localhost:3000/home/stream
我得到了 5 行流回来,没问题。
当我引入nginx时,curl会输出第一行,但之后立即退出。我确实继续看到服务器上的 put 调用的输出和日志,所以我知道该请求仍在 5.times 循环中处理。
它也不会像用户切断连接那样抛出 IOError 异常。
到目前为止,这是我尝试过的:
- 主conf文件中nginx指令的不同组合
服务器配置。
- 更改导轨设置。
- 各种 puma 配置设置。
- 在控制器方法中设置各种不同的标头,希望这是一个缓存问题。
搜索互联网也提供了很少的帮助。
我很茫然,需要一些指导。
这是两个curl 调用的输出,无论是否使用nginx。
没有 Nginx
~/projects/streamtest ▰ master ▰
ryan mirage ▰▰▰▰ curl -i -N http://192.168.1.100:3000/home/stream
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Cache-Control: no-cache
Content-Type: text/html; charset=utf-8
Set-Cookie: request_method=GET; path=/
X-Request-Id: 9ce86358-4476-404a-97e5-769c16ec7b0c
X-Runtime: 0.978099
Transfer-Encoding: chunked
Streaming: 1Streaming: 2Streaming: 3Streaming: 4Streaming: 5
美洲狮标准输出
Streaming: 0
Streaming: 1
Streaming: 2
Streaming: 3
Streaming: 4
[8048] 192.168.1.100 - - [14/Mar/2014 21:04:50] "GET /home/stream HTTP/1.1" 200 - 6.0661
使用 Nginx
~/projects/streamtest ▰ master ▰
ryan mirage ▰▰▰▰ curl -i -N http://192.168.1.100:3000/home/stream
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Sat, 15 Mar 2014 04:02:40 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
ETag: "a505e0aa3b11b25301a9a704252a519a"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: request_method=GET; path=/
X-Request-Id: 8983d199-026b-4082-a5f1-f1d6c886a3d6
X-Runtime: 0.016516
Streaming: 1
美洲狮标准输出
Streaming: 0
[7558] 192.168.1.100 - - [14/Mar/2014 21:02:40] "GET /home/stream HTTP/1.0" 200 - 0.0214
Streaming: 1
Streaming: 2
Streaming: 3
Streaming: 4
有趣的是,我刚刚注意到,获取请求日志行的位置:
“获取/home/stream HTTP/1.0”200
每个curl调用中的值都不同,并且其位置与实际流式传输的文本量相关。
对于这里发生的事情有什么想法吗?为什么在使用 nginx 时 Rails 不能传输整个内容?