如何让ActionController :: Live流与Thin一起使用?

时间:2014-12-14 00:08:52

标签: ruby-on-rails ruby streaming thin actioncontroller

问题

您可以将thinActionController::Live一起使用来实施服务器端事件(SSE)和长轮询吗?如果是这样,怎么样?

上下文

虽然标题是How to get Rails 4 ActionController::Live streaming working with Thin and Ruby 2? And how do Thin and Puma scale with live streaming?的重复,但是OP通过提出两个问题来混淆水域,这个问题从来没有得到解答。

如果您通过thinDoes Heroku support ActionController::Live?Is puma the ONLY multi-threaded rails 4 http server?启动服务器端事件(sse),其他一些帖子建议您可以使用exec thin start --threaded,Aaron的开创性{ {3}}和Ryan的常年可靠http://tenderlovemaking.com/2012/07/30/is-it-live.html。但即使我正在复制Railscast示例,我也无法使用thin

我尝试了什么

# ----------------------------------------------------------------
# file: config/routes.rb
Rails.application.routes.draw do

  resources :widgets do
    collection do
      get 'events'              # SSE test
    end
  end
end

_

# ----------------------------------------------------------------
# file: config/environments/development.rb
Rails.application.configure do
    ... snip ...
    # see http://tenderlovemaking.com/2012/07/30/is-it-live.html
    config.preload_frameworks = true
    config.allow_concurrency = true
end

_

# ----------------------------------------------------------------
# file: app/controllers/widgets_controller.rb
class WidgetsController < ApplicationController
  include ActionController::Live

  # GET /widgets/events
  # see http://railscasts.com/episodes/401-actioncontroller-live?view=asciicast
  def events
    # SSE expects the `text/event-stream` content type
    response.headers['Content-Type'] = 'text/event-stream'
    3.times do |n|
      response.stream.write "#{n}...\n\n"
      sleep 2
    end
  ensure
    response.stream.close
  end

end

_

# ----------------------------------------------------------------
# Gemfile
source 'https://rubygems.org'

gem 'rails', '4.1.8'
gem 'pg'
... snip ...
gem 'thin'

运行它

在shell窗口A:

$ bundle install
Chalcedony[~/Projects/heroku-sample/widget-worker]$ thin start --threaded --trace
Using rack adapter
Thin web server (v1.6.3 codename Protein Powder)
Tracing ON
Maximum connections set to 1024
Listening on 0.0.0.0:3000, CTRL+C to stop

然后在shell窗口B:

$ curl --no-buffer localhost:3000/widgets/events

回到shell窗口A我看到请求,并且响应以一秒的间隔吐出(0...1...2...之间有一秒钟的延迟。这很好:

GET /widgets/events HTTP/1.1
User-Agent: curl/7.37.1
Host: localhost:3000
Accept: */*


HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Content-Type: text/html; charset=utf-8
X-Request-Id: 95e64eb6-ee21-4e97-a33a-dbf579b3027c
X-Runtime: 0.066925
Connection: close
Server: thin


0... <delay...>


1... <delay...>


2... <delay...>

但是在shell窗口B中,打印输出会延迟并立即显示。当我在Chrome中查看该页面时,会发生同样的事情。我是否未能正确配置某些设置?

P.S:

$ rake about
About your application's environment
Ruby version              2.1.4-p265 (x86_64-darwin14.0)
RubyGems version          2.2.2
Rack version              1.5
Rails version             4.1.8
JavaScript Runtime        JavaScriptCore
Active Record version     4.1.8
Action Pack version       4.1.8
Action View version       4.1.8
Action Mailer version     4.1.8
Active Support version    4.1.8
Middleware                Rack::Sendfile, ActionDispatch::Static, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007fb0cb4ae1a0>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::Head, Rack::ConditionalGet, Rack::ETag
Environment               development
Database adapter          postgresql
Database schema version   20141213003938

P.P.S。

现在你可能会想“你为什么不像其他人一样使用puma”好问题。现在,我无法在我的机器上建造美洲狮宝石,原因我还没弄明白。我在大多数heroku部署的应用程序中一直使用thin,所以我很满意。如果我不能瘦下去工作,我会更加努力地建立美洲狮。

1 个答案:

答案 0 :(得分:3)

可悲的是,你不能AC::LiveThin一起使用。这是Mark explaining why以及其他选择。