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