Centrifuge

Code Climate Build Status

Ruby gem for Centrifugo real-time messaging server

Installation

Add this line to your application's Gemfile:

gem 'centrifuge'

And then execute:

$ bundle

Or install it yourself as:

$ gem install centrifuge

Releases

Travis CI configured to automatically release tagged commits to rubygems.

Before tagging, please increment version in lib/centriguge/version.rb and use git tag like v1.1.1.

Dont forget to git push --tags.

Compatibility

Rubycent 1.0.0+ supports only Centrifugo version 1.0.0+ with single project only. If you want to use multiproject Centrifugo, please use rubycent 0.1.0

Usage

Centrifuge::Client - is main usable class. Start with:

    client = Centrifuge::Client.new(scheme: :http, host: :localhost, port: 80, secret: 'cde')

Or just:

    Centrifuge.scheme = :http
    Centrifuge.host = 'localhost'
    Centrifuge.port = 8000
    Centrifuge.secret = 'def'

There are six methods available:

Publish

Sends message to all connected users:

    client.publish('teshchannel', { data: :foo })

You can also use class methods if you set all necessary config data:

    Centrifuge.publish('testchannel', { data: :foo })

Unsubscribe

Unsubscribes user from channel:

    client.unsubscribe('testchannel', 'user#23')

user#23 - is string identificator of user.

Disconnect

Disconnects user from Centrifugo:

    client.disconnect('user#23')

Presence

Gets presence info of the channel:

    client.presence('testchannel')

History

Gets message history of the channel:

    client.history('test_channel')

Channels

Get active channels (with one or more subscribers):

    client.channels()

JS Client token generation

Generates token for JS client:

    client.token_for('testuser', '1443422448')

Where 1443422448 is UNIX timestamp seconds. You can also add user info as valid json string as third parameter:

    client.token_for('testuser', '1443422448', "{}")

Channel Sign token generation

Generates Sign token for a Channel:

client.generate_channel_sign(params[:client], params[:channels], "{}")

Where params[:client] is client passed during authentication and params[:channels] can be an array of channels or a single channel. You can read more here about batching channels here JS Documentation.

You can also add user info as valid json string as third parameter:

client.generate_channel_sign(params[:client], params[:channels], "{"name": "John"}")

On server side using rails, you can authenticate private channels like so:


    #routes.rb or any router lib
    post 'sockets/auth'

    # Auth method to authenticate private channels
    #sockets_controller.rb or anywhere in your app

    # client = Instance of Centrifuge initialized // check Usage section
    # params[:channels] = single/array of channels
    def auth
      if user_signed_in? # Or use a before_filter
        data = {}
        sign = client.generate_channel_sign(
            params[:client], params[:channels], "{}"
        )
        data[channel] = {
            "sign": sign,
            "info": "{}"
        }
        render :json => data
      else
        render :text => "Not authorized", :status => '403'
      end
    end

On client side initialize Centrifuge object like so:


    // client_info = valid JSON string of user_info
    // client_token = client.token_for (described above)

    var centrifuge = new Centrifuge({
       url: "http://localhost:8000/connection",
       user: window.currentUser.id,
       timestamp: window.currentUser.current_timestamp,
       debug: true,
       info: JSON.stringify(window.client_info),
       token: window.client_token,
       refreshEndpoint: "/sockets/refresh",
       authEndpoint: "/sockets/auth",
       authHeaders: {
          'X-Transaction': 'WebSocket Auth',
          'X-CSRF-Token': window.currentUser.form_authenticity_token
       },
       refreshHeaders: {
          'X-Transaction': 'WebSocket Auth',
          'X-CSRF-Token': window.currentUser.form_authenticity_token
       }
     });

    centrifuge.connect();

    // If you using jbuiler use raw render(template_name) and use a global window object to load the user information.

If you want to batch sign channels request to avoid multiple HTTP requests, you can use centrifuge JS client to batch channels centrifuge.startBatching(); // your code // centrifuge.stopBatching(); in one request and on the server iterate through channels and subscribe.

Read more: JS client Documentation

API request sign

When you use Centrifugo server API you should sign each request to successfully authorize with the server.


    # For example this is how you would encode a Publish command
    commands = {
        "method": "publish",
        "params": {
            "channel": "Test",
            "data": { "name": "John Doe" }
        }
    }

    encoded_data = MultiJson.dump(commands) # Or use to_json
    sign = client.sign(encoded_data) #Sign the data

    # Using HTTP party GEM interact with Server API
    r = HTTParty.post(client.url.to_s, query: {"sign": sign, "data": encoded_data})
    r.parsed_response

encoded_data is a JSON string with your API command/commands. See all available commands in Server API chapter.

Rails assets

To use Centrifuge js client just add this line to your application.js manifest:

//= require centrifuge

If you want to use sockjs require it before centrifuge:

//= require sockjs
//= require centrifuge

Other API

Other API methods, like projects and channels management are unavailable now.

Contributing

  1. Fork it ( https://github.com/centrifugal/rubycent/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request