-
Notifications
You must be signed in to change notification settings - Fork 17
WebsocketRails Controllers
Similar to standard Rails requests, each event processed by the server is handled by a fresh instance of your controller object. Any instance variables set in your controller will be wiped out after the action for an event finishes processing. This works great in the standard Rails request/response cycle. However, it is not always convenient for dealing with long running persistent connections such as WebSocket clients. Because of this, we provide our own Controller DataStore object, accessible in a WebsocketRails controller, to make it easier to temporarily store data between events. This is explained further in the DataStore Wiki.
Do not override the initialize method in your class to set up. Instead,
define an initialize_session
method and perform your set up there. The
initialize_session method will be called the first time a controller is
subscribed to an event in the event router. Values added to the
controller data store from inside the initialize_session method will be available throughout the course of the server lifetime.
class ChatController < WebsocketRails::BaseController
def initialize_session
# perform application setup here
controller_store[:message_count] = 0
end
end
You can trigger an event on the client using the send_message
method. The send_message
method takes two arguments, the event name to trigger, and an object to send along with the event.
new_message = {:message => 'this is a message'}
send_message :event_name, new_message
You would handle this event on the client side with the following JavaScript (assuming you already have a dispatcher initialized):
dispatcher.bind('event_name', function(data) {
console.log(data.message) // would output 'this is a message'
});
If the current event was triggered by the client with success and
failure callbacks attached, you can execute them from your controller
action using the trigger_success
and trigger_failure
methods.
Both methods can take an optional object that will be passed to the callback functions on the client.
def awesomeness_approval
if message[:awesomeness] > 5
trigger_success {:message => 'awesome level is sufficient'}
else
trigger_failure {:message => 'awesome level is insufficient'}
end
end
Now you can trigger the awesomeness_approval
event on the
JavaScript client and easily handle the result.
var success = function(response) {
console.log("You are awesome because: "+response.message);
}
var failure = function(response) {
console.log("You are not very awesome because: "+response.message);
}
var message = { awesomeness: 4 }
dispatcher.trigger('awesomeness_approval', message, success, failure);
You can trigger events on all connected clients at once using the broadcast_message
method. It takes the same arguments as the send_message
. If you wish to broadcast to a subset of connected clients, you can use Channels.
new_comment = Comment.latest
broadcast_message :new_comment, new_comment
Namespaced events are triggered from a controller by passing the :namespace
option to the send_message
or broadcast_message
methods.
products = Product.find(:all, :limit => 10)
send_message :new_list, products, :namespace => 'products'
You would bind to this event on the client with the following JavaScript:
dispatcher.bind('products.new_list', function(products) {
console.log('we just received ' + products.size + ' new products!');
});
Event observers are similar to the before_filter
methods in Rails. You can attach a code block to be run when a particular event is triggered within a controller or when any action inside the controller is called.
The following observer will be called any time the new_event
event is triggered:
class EventController < WebsocketRails::Base
observe :new_event do
puts "new_event was called"
end
end
If you want to execute a block before any action in the controller is called regardless of the event, just leave off the event name argument.
class EventController < WebsocketRails::Base
observe do
puts "an event handled by this controller was called"
end
end
Observers will be executed in the same order as they are subscribed.
You can use all of the standard Rails controller helper methods such as url_for
inside of a WebsocketRails Controller. You can also use controller helper methods provided by gems like Devise.