I'm trying to implement text/event-stream using Rails 4's Live streaming. It works great and the only trouble I met is that I can't check if the connection is alive without sending any messages.
The only solution I figured out is to make supportive channel with cyclic tick generator, so that some background task will send messages there periodically. But it seems to be messy and non-reliable. Any better solutions?
Here is my controller:
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
Ok, I found two options:
1) Funny but not good (as I didn't get what sever should I use to handle 1000's of parallel connections):
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) Awesome. To use Goliath server. It turned out that it can check if connection is lost without any ticker. On the way to Goliath found Cramp. It's lightweight and hopefully fast, but seems to be abandonned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With