Redis Pub/Sub and Rails 4 Live Streaming
So today I got to play a bit with the newly minded Rails 4 RC 1. A new feature is Live Streaming so I decided to see how it would work with redis publish / subscribe channels.
So lets create an infinite loop which is publishing on the redis queue “namespaced:stream”
require 'redis'
require 'json'
$i = 1
redis = Redis.new
begin
data = {"time" => "#{ Time.now }" }
redis.publish("namespaced:stream", data.to_json)
sleep 1
$i +=1
end while $i > 0
Lets have that running indefinitely, it is now publishing on the channel namespaced:stream.
Lets install the latest Ruby on Rails 4 and get a streaming controller up and running
class StreamsController < ActionController::Base
include ActionController::Live
def the_stream
response.headers['Content-Type'] = 'text/event-stream'
redis = Redis.new
redis.subscribe('namespaced:stream') do |on|
on.message do |event, data|
response.stream.write("data:#{ data }\n\n")
end
end
ensure
response.stream.close
end
end
end
Make sure you install the puma server and start it.
Now head to /streams/the_stream
Viola, pub/sub with live streaming through Rails 4 + Redis. You could hook up some javascript to access this data.
Stick this in item.js $(document).ready(initialize);
function initialize() {
var source = new EventSource('/products/latest-product-events');
source.addEventListener('message', function(e) {
console.log("Received "+e.data);
updateItemsPage(e.data);
}, false);
source.addEventListener('open', function(e) {
console.log("Connection was opened.");
}, false);
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
console.log("Connection was closed.");
}else{
console.log("Something else");
}
}, false);
};
function updateItemsPage(event) {
var item = $('<li>').text(event);
$('#items').prepend(item);
}
So, why is this cool? Well, firstly it leverages an advanced key-value store, Redis. Next, Rails 4 Live streaming is is a huge advantage. It allows Rails apps to be competitive with Node.js. Unfortunately most Rails application servers are not able to stream, so throw thin + unicorn out. Puma is the way forward it would seem.
Feel free to subscribe to my newsletter, chat to me on mastodon or follow my blog in your favourite RSS reader.