2013-01-10 86 views
17

我正在嘗試使用Rails 4的Live流實現文本/事件流。它工作的很好,唯一遇到的麻煩是我無法檢查連接是否活着而不發送任何消息。ActionController :: LIve是否有可能檢查連接是否仍然存在?

我想出的唯一解決方案是使用循環刻度生成器來創建支持通道,以便一些後臺任務將定期發送消息。但它似乎是混亂和不可靠的。有更好的解決方案

這裏是我的控制器:

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 
+0

另一個選項在這裏詳細說明:http://stackoverflow.com/a/19485363/928963 –

+0

看起來像下面所示的完全相同,除了它使用redis發出更復雜的時鐘信號。畢竟它在負載下如何工作?初始化器是否在每個請求上觸發?這可能會使pub/sub頻道超載,每個客戶端都會收到來自所有客戶端的消息。 –

+0

下面的解決方案是爲每個客戶端連接觸發額外的代理線程。我在我引用的答案中提出的解決方案有一個用於推出這些代碼的單一線程,這個代碼縮放得更好一些。 (並且,將它放入初始化程序會爲每個導入進程創建一個線程,而不是每個客戶端連接) –

回答

10

好吧,我發現了兩個選項:

1)滑稽,但也不好(因爲我沒有得到我應該用什麼服務器來處理並行的1000年連接):

begin 
    ticker = Thread.new { loop { sse.write 0; sleep 5 } } 
    sender = Thread.new do 
    redis.subscribe(:info, :chat) do |on| 
     on.message do |event, message| 
     sse.write(message, :event => event.to_s) 
     end 
    end 
    end 
    ticker.join 
    sender.join 
rescue IOError 
ensure 
    Thread.kill(ticker) if ticker 
    Thread.kill(sender) if sender 
    track.close 
    sse.close 
end 

2)太棒了。使用Goliath服務器。事實證明,它可以檢查連接是否丟失,沒有任何股票。在去哥利亞的途中發現了Cramp。它輕巧,希望速度快,但似乎被放棄。

相關問題