Rails流式传输并非真正的流式传输。

8
我正在为我的Rails应用程序添加流式组件,因为我想开始使用SSE。我已经尝试在一个较小的示例中使其正常工作,但仍然有困难。我一直无法让Rails正确地向curl请求流式传输响应。我正在按照http://tenderlovemaking.com/2012/07/30/is-it-live.html上的教程进行操作。我不确定是否需要为OSX配置一些东西或者我的配置中是否遗漏了某些内容。任何帮助都将不胜感激。
我正在本地的OSX上运行此应用程序。当我运行curl-i localhost:3000时,我会得到以下响应:
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
Content-Type: text/event-stream
Last-Modified: Wed Apr 23 23:10:15 2014
Cache-Control: no-cache
Set-Cookie: request_method=GET; path=/
X-Request-Id: 89f2af3e-76e9-4873-85b0-3b6fe45f6343
X-Runtime: 0.001724
Transfer-Encoding: chunked

hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world

问题是我一次性获取到所有响应,而不是按预期逐步获取响应的部分。如果需要更多信息,请告诉我。
我的代码如下:
stream_test_controller.rb
class StreamTestController < ActionController::Base
  include ActionController::Live

  def index
    response.headers['Content-Type'] = 'text/event-stream'
    10.times {
      logger.info "hello world sent"
      response.stream.write "hello world\n"
      sleep 1
    }
    response.stream.close
  end
end

Gemfile

source 'https://rubygems.org'  
ruby '2.1.0'

gem 'rails', '4.0.3'
gem 'sqlite3'
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
gem 'puma'

group :doc do
  gem 'sdoc', require: false
end

development.rb

StreamTest::Application.configure do

  config.preload_frameworks = true
  config.allow_concurrency = true
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development    
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = true

  # Do not eager load code on boot.
  config.eager_load = true

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Raise an error on page load if there are pending migrations
  config.active_record.migration_error = :page_load

  # Debug mode disables concatenation and preprocessing of assets.
  # This option may cause significant delays in view rendering with a large
  # number of complex assets.
  config.assets.debug = true
end

你的curl命令运行需要10秒钟吗? - Mike H-R
1
是的,我刚试过了,甚至在每次迭代中添加了一个日志文件,确保在执行curl命令之前它完全运行。 - rsaris
3个回答

1

你是使用WEBrick进行测试吗?如果是,请参考这里的文档

WEBrick服务器会缓冲所有响应,所以包括ActionController::Live将无法正常工作。您必须使用不自动缓冲响应的Web服务器。


可能不会。他的 Gemfile 包括 puma gem。 - SreekanthGS
是的,我在使用puma。我也尝试过使用puma命令启动服务器,但没有起作用。 - rsaris
@rsaris 是指 rails s Puma 吗? - Matt Gibson
我通常只是运行rails s,但它似乎以与运行rails s Puma相同的方式启动。我还尝试使用puma命令启动它,但使用curl命令时没有任何不同。 - rsaris

1

尝试在curl命令中禁用缓冲。从手册中可以看到:

-N,--no-buffer

禁用输出流的缓冲。在正常工作情况下,curl将使用标准缓冲输出流,这将导致它以块的形式输出数据,而不一定是数据到达时立即输出。使用此选项将禁用该缓冲。


1
谢谢您的回复。我尝试了运行 curl --no-buffer -i localhost:3000curl --no-buffer localhost:3000,但都没有成功。看起来不是 curl 的缓冲引起了这个问题。我也尝试了在 Chrome 中打开,但也没有成功。 - rsaris

0

SSE消息由两个换行符(link)分隔。

您的代码应该包含:

response.stream.write "hello world\n\n"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接