Build Status Code Climate

Garufa

An open source server implementation of the Pusher protocol.

Intro

Garufa is a Ruby websocket server which implements the Pusher protocol. It is built on top of Goliath, a high performance non-blocking web server, and inspired by Slanger, another server compatible with Pusher.

Install

Be sure you have a ruby version >= 1.9.2

$ gem install garufa

$ garufa --help

Usage

Start garufa server:

$ garufa -sv --app_key app-key --secret app-secret

This will start Garufa, logging to stdout in verbose mode. If you want Garufa to run in background (daemonized) add -d flag.

Now say you want to send events to your browser. Create an .html file which requires the pusher.js library and binds to some events, then point your browser to that file (for testing purpose, you can simply open it with your browser).

Maybe you would like to open your JavaScript console to see JavaScript debug messages.

<html>
  <script src="http://js.pusher.com/2.1/pusher.min.js"></script>
  <script>
    Pusher.log = function(message) { console.log(message) };
    Pusher.host = 'localhost';
    Pusher.ws_port = 8080;

    var appKey = 'app-key';
    var pusher = new Pusher(appKey);
    var channel = pusher.subscribe('my-channel');

    channel.bind('my-event', function(data) { alert(data.message) });
  </script>
</html>

Now trigger my-event from Ruby code. Be sure you have already installed the pusher gem (gem install pusher). Open a Ruby console and paste this:

require 'pusher'

Pusher.host = 'localhost'
Pusher.port = 8080

Pusher.app_id = 'my-app'
Pusher.key = 'app-key'
Pusher.secret = 'app-secret'

Pusher.trigger('my-channel', 'my-event', { message: 'hello world' })

Check your browser to see the event have just arrived.

SSL support

$ garufa -sv --app_key app-key --secret app-secret --ssl --ssl-cert /path/to/cert.pem --ssl-key /path/to/cert.key

NOTE: At the moment, Garufa uses the same port for API messages and websocket connections. This means that if you start the server with SSL enabled, you will have to enable SSL in the client library as well as in the api client.

An alternative is to setup Garufa behind a reverse proxy such as Nginx and let the proxy take care of SSL. See below for more info.

Using Nginx as reverse proxy

You can set Garufa behind Nginx if you want: http://nginx.org/en/docs/http/websocket.html

Take into account that you will need to set proxy_read_timeout to a value a little higher than Pusher ACTIVITY_TIMEOUT, otherwise Nginx will close the connection.

In addition, you can let Ngnix take care of SSL and start Garufa without SSL enabled. You could use something like this in your Nginx configuration.

upstream garufa {
    server 127.0.0.1:8000;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen       8080;
    server_name  garufa.example.com;

    ; Set this a little higher than Pusher ACTIVITY_TIMEOUT
    proxy_read_timeout  150;

    ssl                  on;
    ssl_certificate      /path/to/cert.pem;
    ssl_certificate_key  /path/to/cert.key;

    location / {
        proxy_pass          http://garufa;
        proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection $connection_upgrade;
    }
}

Setting up Garufa on Heroku

Create a repo for your app:

$ mkdir garufa-heroku
$ cd garufa-heroku
$ git init .

Create Gemfile and Procfile files:

# Gemfile
source 'http://rubygems.org'
ruby '2.1.2'
gem 'garufa'

# Procfile
web: garufa -v --app_key $GARUFA_APP_KEY --secret $GARUFA_SECRET -p $PORT

Generate Gemfile.lock and commit your changes:

$ bundle install
$ git add .
$ git commit -m 'Initial commit'

Create your app, set environment variables and deploy:

$ heroku create
$ heroku config:set GARUFA_APP_KEY=app-key
$ heroku config:set GARUFA_SECRET=app-secret
$ git push heroku master

At this point you should have Garufa up and listening on port 80.

Set Pusher.port and Pusher.ws_port in the example above to port 80, and Pusher.host to the name of your app provided by Heroku (something like random-name-2323.herokuapp.com).

Testing and Contributing

It's up to you how you install Garufa dependencies for development and testing, just be sure you have installed dependencies listed in the .gemspec. If you want to let bundler handle this, you can generate a Gemfile from the .gemspec and then run bundle install.

$ bundle init --gemspec=garufa.gemspec
$ bundle install

Once you have dependencies installed, run rake test (or just rake).

$ rake

Pull requests are welcome!

Pusher

Pusher is a great service, very well documented and with excellent support. Consider using it on production.