Skip to content

Instantly share code, notes, and snippets.

@isaiah
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isaiah/c02d0aed6f2eefe6037b to your computer and use it in GitHub Desktop.
Save isaiah/c02d0aed6f2eefe6037b to your computer and use it in GitHub Desktop.
Rails live streaming sample
$ curl localhost:8080 -I
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "0f8cca87cff164a57033f54d75dc1288"
Cache-Control: max-age=0, private, must-revalidate
X-Runtime: 0.017000
Server: Jubilee(2.1.0)
Transfer-Encoding: chunked
Date: Thu, 24 Jul 2014 14:38:03 GMT
require "action_controller/railtie"
require "rails/test_unit/railtie"
class HelloWorld < Rails::Application
routes.append do
root "hello#world"
get "/stream" => "my#stream"
end
config.cache_classes = true
config.eager_load = true
config.secret_key_base = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
["Rack::Lock", "ActionDispatch::Flash", "ActionDispatch::BestStandardsSupport",
"Rack::Sendfile", "ActionDispatch::Static", "Rack::MethodOverride",
"ActionDispatch::RequestId", "Rails::Rack::Logger",
"ActionDispatch::ShowExceptions", "ActionDispatch::DebugExceptions",
"ActionDispatch::RemoteIp", "ActionDispatch::Callbacks",
"ActionDispatch::Cookies", "ActionDispatch::Session::CookieStore",
"ActionDispatch::ParamsParser", "Rack::Head", "Rack::ConditionalGet"].each do |middleware|
config.middleware.delete(middleware)
end
end
class MyController < ActionController::Base
include ActionController::Live
def stream
response.headers['Content-Type'] = 'text/event-stream'
100.times {
response.stream.write "hello world\n"
sleep 1
}
ensure
response.stream.close
end
end
$ curl localhost:8080/stream -I
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
Cache-Control: no-cache
X-Runtime: 0.019000
Server: Jubilee(2.1.0)
Transfer-Encoding: chunked
Date: Thu, 24 Jul 2014 14:38:15 GMT
@isaiah
Copy link
Author

isaiah commented Jul 24, 2014

Rack::Etag has no effect on the streaming request at all!

@dimitarvp
Copy link

Common scenario -- masking the underlying storage (S3, GCS, Rackspace etc.) via authenticated API urls to our own backend. So something like curl our-app.com/videos/123/download should start streaming the video immediately after receiving the first chunk of the file fetched from the underlying storage.

So, are you open to making a similar GIST for binary files?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment