Puller

Puller is a Ruby gem for use with Rails to publish and subscribe to messages through Pusher. It allows you to easily provide real-time updates through an open socket without tying up a Rails process.

Its code and API design is heavily inspired by Ryan Bates' PrivatePub.

Setup

Add the gem to the Gemfile of your Rails application and run the bundle command to install it.

gem "puller"

In Rails 3.1 add the JavaScript file to your application.js file manifest.

//= require puller

In Rails 3.0 run the generator to create the initial files

rails g puller:install

and add the generated puller.js file to your layout.

<%= javascript_include_tag "puller" %>

It's not necessary to include pusher.js since that will be handled automatically for you.

Configure your Pusher credentials in an initializer file.

Pusher.app_id = 'my_pusher_app_id'
Pusher.key    = 'my_pusher_api_key'
Pusher.secret = 'my_pusher_secret'

Note: You can skip this step if you are on Heroku and have activated the Pusher addon for your app.

Usage

Use the subscribe_to helper method on any page to subscribe to a channel/event.

<%= subscribe_to "new-message" %>

The above method subscribes to the "new-message" event in the default channel. The default channel name is the parameterized form of your Rails' application name. To use a different channel, prepend your custom channel name to the argument followed by a colon:

<%= subscribe_to "my-channel:new-message" %>

Use the publish_to helper method to send JavaScript to that channel/event. This is usually done in a JavaScript AJAX template (such as a create.js.erb file).

<% publish_to "new-message" do %>
  $("#chat").append("<%= j render(@message) %>");
<% end %>

This JavaScript will be immediately evaluated on all clients who have subscribed to that channel. In this example they will see the new chat message appear in real-time without reloading the browser.

Alternative Usage

If you prefer to work through JSON instead of .js.erb templates, you can pass a hash to publish_to instead of a block and it will be converted to_json behind the scenes. This can be done anywhere (such as the controller).

Puller.publish_to "new-message", :chat_message => "Hello, world!"

And then handle this through JavaScript on the client side.

Puller.subscribe("new-message", function(data, channel) {
  $("#chat").append(data.chat_message);
});

The Ruby subscribe_to helper call is still necessary with this approach to grant the user access to the channel. The JavaScript is just a callback for any custom behavior.

Development & Feedback

Questions or comments? Please use the issue tracker. Tests can be run with bundle and rake commands.