I'm trying to use Live Streaming in Rails 4.0.1 in one project but I see problems...
I have this action:
def realtime_push response.headers['Content-Type'] = 'text/event-stream' sse = SSE.new(response.stream) d = Domain.find(params[:domain_id]) begin loop do backlinks = d.backlinks.page(params[:page]).per(10) pagination = render_to_string(:partial => 'backlinks/pagination', :layout => false, :locals => { :backlinks => backlinks }) sse.write({ :html => pagination }, :event => 'pagination') sleep 1 end rescue IOError # When the client disconnects, we'll get an IOError on write logger.debug "DISCONNECTED" ensure sse.close end end
When I start Puma and try to get updates:
curl http://localhost:3000/domains/16/backlinks/realtime_push
curl immediately returns with no output.
Curl headers:
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-Request-Id: 1a07be2f-de8d-4ca8-87d0-eee2787ea649 X-Runtime: 0.250782 Transfer-Encoding: chunked
and Puma log shows:
Started GET "/domains/16/backlinks/realtime_push" for 127.0.0.1 at 2013-11-08 12:22:30 +0100 ActiveRecord::SchemaMigration Load (0.7ms) SELECT "schema_migrations".* FROM "schema_migrations" Processing by BacklinksController#realtime_push as */* Parameters: {"domain_id"=>"16"} Domain Load (1.9ms) SELECT "domains".* FROM "domains" WHERE "domains"."id" = $1 LIMIT 1 [["id", "16"]] (3.3ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (60.6ms) (0.6ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (36.0ms) (0.8ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (37.5ms) (0.8ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (35.6ms) (0.7ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (38.7ms) (0.7ms) SELECT COUNT(*) FROM "backlinks" WHERE "backlinks"."domain_id" = $1 [["domain_id", 16]] Rendered backlinks/_pagination.haml (37.0ms)
So these things are strange:
- curl returned no output
- log says it rendered pagination 6 times
- there was no "DISCONNECT" message in the log
Any ideas? If I comment out the two lines above sse.write and return some text instead of pagination contents, it works...
Here is the SSE class:
class SSE def initialize io @io = io end def write object, options = {} options.each do |k,v| @io.write "#{k}: #{v}\n" end @io.write "data: #{JSON.dump(object)}\n\n" end def close @io.close end end