View on GitHub

Realtime-rails

Download this project as a .zip file Download this project as a tar.gz file

Realtime Support for Rails

This gem enables you to communicate with your rails front-end in realtime, leveraging socket.io, redis (or ZeroMQ), and node.js. Clients are authenticated via their user id plus a day-long shared session token between the servers.

Note: This gem is a concept piece originally conceived in 2013 and published as a generic open source project in early 2014. As of mid-2015, support for performant, native and scalable websockets are available in Rails. See ActiveCable ActionCable, which landed in Rails 5 and will probably be officially released early/mid 2016. As such, with ActionCable's design, you don't even need a separate pub/sub server (redis) and Node.js running anymore to achieve similar lightweight realtime bi-directional communication with a large number of connected clients to your Rails application. Progress marches forward! I presume, if you are stuck and can't upgrade to Rails 5 anytime soon, perhaps this project is lightweight compared to some of the heavier alternatives like Faye or PubNub.

This gem, and sample node.js servers were inspired by the blog post: Liam Kaufman's Adding Real-Time to a RESTful Rails App.

A live demo of this in action using redis is at Realtime-rails Demo on Heroku. A diagram of this in action:

A live demo of this in action using ZeroMQ is at Realtime-rails-zmq Demo. A diagram of this in action:

To start, install the gem in your Gemfile:

gem 'realtime'

If you want to use redis for your realtime backend, first, install redis:

For OS X, with homebrew:

brew install redis

For more information on installing redis locally on other platforms, see http://redis.io/topics/quickstart

next, include in your Gemfile:

gem 'redis'

and then run:

bundle install

If you want to use embedded ZeroMQ for your realtime backend, you'll need to install ZeroMQ, and then include:

gem 'zmq'
gem 'em-zmq'

and then run:

bundle install

Next, you'll need to tell your application_controller.rb that it is sharing a realtime token with your realtime server by adding the following lines:

  # app/controllers/application_controller.rb

  realtime_controller({:queue => :redis}) # instruct all requests to enable realtime support via redis
  # realtime_controller({:queue => :zmq}) # instruct all requests to enable realtime support via zmq

  def realtime_user_id
    return 42 # if using devise, change this to current_user.id
  end

  def realtime_server_url
    # point this to your node.js-socket.io-redis/zmq realtime server (you can set this later)
    return 'http://your-realtime-server.yourdomain.com'
  end

In your application.html.erb file, add the following to your <head> element:

 <!-- required: realtime support framework -->
 <%= realtime_support %>
 <!-- optional: message_handler dequeues realtime messages into Backbone.js style events -->
 <%= realtime_message_handler %>
 <!-- optional: message_console_logger listens or dequeues realtime messages to the browser console -->
 <%= realtime_message_console_logger %>

If using redis, tell rails about your redis instance:

# config/initializers/redis.rb
location = ENV["REDISCLOUD_URL"] || 'redis://127.0.0.1:6379/0'
uri = URI.parse(location)
$redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)

If using ZeroMQ, tell rails about the ZeroMQ endpoint:

# config/initializers/zero_mq.rb
$zero_mq = "tcp://zmq-server.mikeatlas.com:5556"

Now, you'll need to run a realtime node.js server (you can use my sample realtime server). If you host this Node.js server on Heroku, you'll need to enable websockets for this application.

gem install foreman
git clone git://github.com/mikeatlas/realtime-server.git
cd realtime-server
sudo npm install
foreman start

If you want to use the ZeroMQ enabled realtime server, you'll probably run into trouble standing it up on Heroku since the library is not installed on the Cedar stack by default, so my recommendation is to run it on an Amazon EC2 instance (be sure to open up ports 80, 5001, 5556 and 5557). You'll need to install ZeroMQ, and run:

gem install foreman
git clone git://github.com/mikeatlas/realtime-server-zmq.git
cd realtime-server-zmq
sudo npm install
foreman start

Now that you have rails running and connecting to redis/ZeroMQ, and node.js running and connecting, you should be able to try it out. Connect to your rails console rails c and run the following command:

# if using redis:
$redis.publish 'realtime_msg', {msg: 'hello world - ' + SecureRandom.hex, recipient_user_ids: [41, 42]}.to_json
# if using ZeroMQ:
ZmqWrapper.publish({msg: 'hello world - ' + SecureRandom.hex, recipient_user_ids: [41, 42]})

If you are user id 42 in the rails application, you should see in your browser console something like:

Object {msg: "hello world - e008f94a8710826bad8c4f6af28be922"}