2013-01-10 22 views
17

Próbuję zaimplementować tekst/strumień zdarzeń za pomocą transmisji strumieniowej na żywo Rails 4. Działa świetnie i jedyny problem, jaki napotkałem, to to, że nie mogę sprawdzić, czy połączenie jest żywe bez wysyłania jakichkolwiek wiadomości.ActionController :: LIve Czy można sprawdzić, czy połączenie jest nadal aktywne?

Jedyne rozwiązanie, jakie wymyśliłem, to utworzenie kanału wspomagającego z cyklicznym generatorem znaczników, aby niektóre zadania w tle wysyłały tam okresowo komunikaty. Ale wydaje się być niechlujny i niewiarygodny. Jakieś lepsze rozwiązania?

Oto mój kontroler:

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

Kolejna opcja opisana tutaj: http://stackoverflow.com/a/19485363/928963 –

+0

Wygląda dokładnie tak samo, jak pokazano poniżej, z wyjątkiem tego, że używa redis do wysyłania sygnału zegara, który jest bardziej złożony. I w końcu, jak będzie działać pod obciążeniem? Czy inicjalizator nie uruchamia się na każde żądanie? Może to spowodować przeciążenie kanału pub/sub, a każdy klient otrzyma wiadomości od wszystkich klientów. –

+0

Rozwiązanie, które masz poniżej, wyzwala dodatkowy wątek na klienta. Rozwiązanie, które zaproponowałem w mojej odpowiedzi, do której się odwołałem, ma jeden wątek do wypychania tych tickerów, który jest nieco lepszy. (I, umieszczając go w inicjalizatorze tworzy jeden wątek na proces szyny, a nie na połączenie klienta) –

Odpowiedz

10

Ok, znalazłem dwie opcje:

1) Zabawne, ale nie dobre (jak nie dostać co Sever powinno się używać do obsługi 1000 na równoległej połączenia):

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) Niesamowite. Aby korzystać z serwera Goliath. Okazało się, że może sprawdzić, czy połączenie zostanie utracone bez tickera. W drodze do Goliata znaleziono Crampa. Jest lekki i mam nadzieję, że szybko, ale wydaje się być porzucony.

Powiązane problemy