-
Notifications
You must be signed in to change notification settings - Fork 17
WebsocketRails Controllers
There are a few differences between WebSocket controllers and standard Rails controllers. The biggest of which, is that each event will be handled by the same, continually running instance of your controller class. This means that if you set any instance variables in your methods, they will still be available when the next event is processed. On top of that, every single client that is connected will share these same instance variables. This can be an advantage if used properly, but it can also lead to bugs if not expected. We provide our own DataStore object accessible in a WebsocketRails controller to make it easier to store data isolated from each connected client. This is explained further below.
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. Instance variables defined in 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
@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'
});
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.