Using Private Channels

Muhammad Al-Syrwan edited this page Apr 24, 2015 · 12 revisions

Private channels give you the ability to authorize a user's subscription using the authorization mechanism of your choice.

You can specify which channels you wish to make private inside of the event router using the private_channel method.

WebsocketRails::EventMap.describe do
  private_channel :secret_posts
  private_channel :members_only
end

Or you can always mark any channel as private later on from anywhere inside of your Rails application.

WebsocketRails[:secret_posts].make_private

Handling the authorization is simple as well. Just subscribe the websocket_rails.subscribe_private event to the controller and action of your choice.

WebsocketRails::EventMap.describe do
  namespace :websocket_rails do
    subscribe :subscribe_private, :to => AuthorizationController, :with_method => :authorize_channels
  end
end

WebsocketRails::BaseController offers the accept_channel and deny_channel methods to help with channel authorization. They will trigger the appropriate callback on the channel.

You can also pass an object to the accept and deny methods that will be passed to the success or failure callback functions on the client channel.

Here is an example of handling the authorization in your controller using the CanCan Gem.

class AuthorizationController < WebsocketRails::BaseController
  def authorize_channels
    # The channel name will be passed inside the message Hash
    channel = WebsocketRails[message[:channel]]
    if can? :subscribe, channel
      accept_channel current_user
    else
      deny_channel({:message => 'authorization failed!'})
    end
  end
end

On the client side, you can use the dispatcher.subscribe_private() method to subscribe to a private channel.

var private_channel = dispatcher.subscribe_private('channel_name', function(current_user) {
  // success callback
  console.log( current_user.name + " has joined the channel" );
}, function(reason) {
  // failure callback
  console.log( "Authorization failed because " + reason.message );
});

By default, all subscribers in to a channel will be removed when that channel is made private. If you don't wish active subscribers to be removed from a previously public channel when making it private, uncomment and set the following in config/initializers/websocket_rails.rb to true.

config.keep_subscribers_when_private = true