【发布时间】:2013-01-10 22:47:18
【问题描述】:
我正在尝试使用 Rails 4 的实时流实现文本/事件流。它工作得很好,我遇到的唯一问题是我无法在不发送任何消息的情况下检查连接是否存在。
我想出的唯一解决方案是使用循环滴答发生器制作支持通道,以便一些后台任务会定期在那里发送消息。但它似乎是混乱和不可靠的。有更好的解决方案吗?
这是我的控制器:
require 'persistency/sse'
require 'persistency/track'
class PersistencyController < ApplicationController
include ActionController::Live
def stream
response.headers['Content-Type'] = 'text/event-stream'
sse = Persistency::SSE.new(response.stream)
track = Persistency::Track.new(current_user)
redis = Redis.new
begin
redis.subscribe(:info, :chat) do |on|
on.message do |channel, message|
sse.write({ :message => message }, :event => channel)
end
end
rescue IOError
ensure
track.close
sse.close
end
end
end
【问题讨论】:
-
此处详述另一个选项:stackoverflow.com/a/19485363/928963
-
看起来和下图完全一样,只是它使用redis来发出时钟信号,这更复杂。毕竟它在负载下将如何工作?不是每个请求都会触发初始化程序吗?这可能会使发布/订阅通道过载,每个客户端都会从所有客户端获取消息。
-
您下面的解决方案是为每个客户端连接触发一个额外的代码线程。我在我引用的答案中提出的解决方案有一个用于推出这些代码的单线程,它可以更好地扩展。 (并且,将它放在初始化程序中会为每个 rails 进程创建一个线程,而不是每个客户端连接)
-
我没有看到每个连接有一个轻线程循环运行的问题。您建议使用什么服务器? Puma 是我所知道的最多线程的,甚至 Puma 也有工人的概念,因此您的滴答频道将拥有与您拥有的工人/进程一样多的消息。那是我的恕我直言。无论如何,我建议你看看歌利亚:postrank-labs.github.io/goliath
标签: ruby-on-rails publish-subscribe event-stream