问题
你能否使用thin
和ActionController::Live
实现服务器端事件(SSE)和长轮询? 如果可以,如何实现?
背景
虽然标题重复了如何在Thin和Ruby 2上实现Rails 4 ActionController::Live流媒体功能?,但 OP 提出了两个问题,而这个问题从未得到回答。
许多其他帖子建议您可以通过exec thin start --threaded
启动thin
来使用服务器端事件(sse): Heroku是否支持ActionController::Live? 和 Puma是唯一的多线程Rails 4 HTTP服务器吗?,Aaron的经典文章http://tenderlovemaking.com/2012/07/30/is-it-live.html和 Ryan永恒可靠的http://railscasts.com/episodes/401-actioncontroller-live?view=asciicast。但即使我复制了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'
运行它
在 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
P.P.S.
现在你可能会想:“为什么你不像其他人一样使用puma
呢?” 这是个好问题。 目前,由于我还没有找到原因,无法在我的电脑上构建puma
gem。同时,在我的大多数heroku部署的应用中,我一直在使用thin
,所以我对它很熟悉。 如果我无法让thin
正常工作,我将更加努力地构建puma
。
close
,对于流式事件来说。你描述的效果就像根本没有流式传输,而是等待所有数据通过然后刷新。我没有答案,但也许这会有所帮助。我迫切地等待着有更多经验的人来解答! - Chuck Vose