ActionController :: Live与SSE一起无法正常工作 [英] ActionController::Live with SSE not working properly
问题描述
我正在尝试在一个项目中的Rails 4.0.1中使用实时流,但是我看到了问题...
I'm trying to use Live Streaming in Rails 4.0.1 in one project but I see problems...
我有这个动作:
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并尝试获取更新时:
When I start Puma and try to get updates:
curl http://localhost:3000/domains/16/backlinks/realtime_push
卷曲立即返回,没有任何输出.
curl immediately returns with no output.
卷曲标题:
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)
所以这些事情很奇怪:
- 卷曲没有输出
- 日志说它分页了6次
- 日志中没有"DISCONNECT"消息
有什么想法吗?如果我注释掉sse.write上方的两行并返回一些文本而不是分页内容,那么它将起作用...
Any ideas? If I comment out the two lines above sse.write and return some text instead of pagination contents, it works...
这是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
推荐答案
这是render_to_string中的错误.
This is a bug in render_to_string.
修复此问题的猴子补丁(实际上不能解决问题-见下文):
Monkey patch to fix this (that actually doesn't fix the problem - see below):
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(服务器发送的事件)不起作用
UPDATE: this only appears to fix the problem... although it will cause the controller to actually send the data, the receiving end in JavaScript for some reason still won't get notified of events, see here: SSE (Server-sent events) not working
这篇关于ActionController :: Live与SSE一起无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!