Using Pusher gem with your Rails app


Easy setup websockets in your Rails app with Pusher, check https://pusher.com.

Let’s say we are implementing delayed reports generation, first we are sending request to our backend with report params. Next, while our Sidekiq jobs are in progress we can listen to websocket and update user UI after success status.

Let’s do it!

Adding gem to your project

gem 'dotenv-rails'
gem 'pusher'
gem 'rails-assets-pusher', source: 'https://rails-assets.org'

Next, setup ENV vars with your secret keys.

PUSHER_APP_ID=53523523
PUSHER_KEY=d6cae246732c5ae7432d
PUSHER_SECRET=0f6ba789234db64f7894

Let’s configure Pusher in your app, for example in pusher.rb file on your Rails initializers directory.

require 'pusher'

Pusher.app_id = ENV.fetch('PUSHER_APP_ID')
Pusher.key = ENV.fetch('PUSHER_KEY')
Pusher.secret = ENV.fetch('PUSHER_SECRET')
Pusher.cluster = 'us2'
Pusher.logger = Rails.logger
Pusher.encrypted = true 

In your Sidekiq job add code which will be responsible for Pusher trigger.

  filename = ExportCommand.run(options)
  Pusher.trigger('exports_' + options['model_name'].downcase, 'generate', {
    filename: filename
  })

And finally, somewhere in our assets, let’s configure and run UI related code:

//= require pusher
//= require jquery
//= require jquery_ujs

Pusher.logToConsole = true;

var pusher = new Pusher('d5cae678934c5ae5213d', {
  cluster: 'us2',
  encrypted: true
});

$(document).on('ready', function() {
  $('.exporter').click(function(event) {
    var that = $(this);
    var channel = pusher.subscribe('exports_' + that.data('model'));
    var result = $(that).parent().find('.result');
    event.preventDefault();
    $.ajax({
      method: 'GET',
      url: window.location.href,
      data: {
        export: that.data('model'),
      },
      beforeSend: function() {
        result.removeClass('hidden');
        result.html('Processing...');
      },
      success: function(data) {
        channel.bind('generate', function(data) {
          var downloadLink = $("<a />", {
            href : '/downloads/get/' + data.filename,
            text : "Download"
          });
          result.html(downloadLink);
        });
      }
    });
  });
});

Only five simple steps and zero headache! Enjoy your websockets.