【发布时间】:2014-12-14 00:08:52
【问题描述】:
问题
您能否使用thin 和ActionController::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通过问两个问题来搅浑水,这个问题一直没有得到回答。
如果您通过exec thin start --threaded 启动它,许多其他帖子建议您可以将thin 用于服务器端事件(sse):Does Heroku support ActionController::Live? 和Is puma the ONLY multi-threaded rails 4 http server?,Aaron 的开创性http://tenderlovemaking.com/2012/07/30/is-it-live.html 和Ryan 的长期可靠@987654325 @。但即使我正在复制 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 中查看页面时,也会发生同样的事情。我是否未能正确配置某些设置?
附注:
$ 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
附言
现在你可能在想“你为什么不像其他人一样使用puma?”好问题。现在,由于我还没有弄清楚的原因,我无法在我的机器上构建 puma gem。我在大多数 Heroku 部署的应用程序中都使用了thin,所以我很满意。如果我不能瘦下来工作,我会更加努力地打造 puma。
【问题讨论】:
-
我之前的评论是不正确的(或者可能是正确的,但最好是出于错误的原因)。
-
好的,仔细阅读,我觉得 curl 上的连接标头不应该是
close用于流式事件。您描述的效果就像它根本不是流式传输,而是等到所有数据都通过然后刷新。我没有答案,但也许这会有所帮助。我热切期待有更多经验的人!
标签: ruby-on-rails ruby streaming thin actioncontroller