我正在尝试在一个项目中使用Rails 4.0.1中的直播,但我发现问题......
我有这个动作:
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
当我开始使用Puma并尝试获取更新时:
curl http://localhost:3000/domains/16/backlinks/realtime_push
卷曲立即返回,没有输出。
卷曲标题:
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
和Puma日志显示:
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)
所以这些事情很奇怪:
有什么想法吗?如果我将sse.write上面的两行注释掉并返回一些文本而不是分页内容,那么它就可以...
这是SSE课程:
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
答案 0 :(得分:1)
这是render_to_string中的错误。
修补此问题的补丁(实际上无法解决问题 - 请参阅下文):
def render_to_string(*)
orig_stream = response.stream
super
ensure
if orig_stream
response.instance_variable_set(:@stream, orig_stream)
end
end
来源:http://blog.sorah.jp/2013/07/28/render_to_string-in-ac-live
更新:这只出现来修复问题...虽然它会导致控制器实际发送数据,但由于某些原因,JavaScript中的接收端仍然不会收到事件通知,见这里:SSE (Server-sent events) not working