Installation
- Get the plugin from: http://rubyforge.org/frs/?group_id=1884 or alternatively get it from the svn: svn://rubyforge.org//var/svn/juggernaut/trunk/juggernaut and put it in the dir: vendor/plugins
- Run: rake install_juggernaut
- If you're going to use prototype/scriptaculous then add the default javascripts to your view (not required):
<%= javascript_include_tag :defaults %> - Add this to your view/layout header
<%= javascript_include_tag "juggernaut_javascript" %> - Add this to your view/layout body:
<%= flash_plugin(session[:juggernaut_channels]) %> - Install the Json library (gem install json).
- Configure the ports and host. This is very important as flash will only allow you to make a socket connection to the same host as the address the client is viewing. Configure the ports in config/juggernaut_config.yml.
And you are all set!
Usage
To demonstrate Juggernaut I'll walk you through building a simple chat.
Start the push server going by running:
ruby script/push_server
The chat controller:
def indexThe index.rhtml
session[:juggernaut_channels] = ["chat_channel"]
end
def send_data
input_data = Juggernaut.html_and_string_escape(params[:chat_input])
data = "new Insertion.Top('chat_data','<li>#{input_data}</li>');"
Juggernaut.send(data,session[:juggernaut_channels])
render :nothing => "true"
end
<html>
<head>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "juggernaut_javascript" %>
</head>
<body>
<%= form_remote_tag(
:url => { :action => :send_data },
:complete => "$('chat_input').value = ''" ) %>
<%= text_field_tag( 'chat_input', '', { :size => 20, :id => 'chat_input'} ) %>
<%= submit_tag "Add" %>
<%= end_form_tag %>
<ul id="chat_data" style="list-style:none">
</ul>
<%= flash_plugin(session[:juggernaut_channels]) %>
</body>
</html>
Start the webserver going with:
ruby script/server
Try it and see what you think. If it doesn't work please visit the faq.
As soon as the page loads the 'flash plugin' opens a socket to the push server and subscribes to the appropriate channels. In this case I'm storing the channels I want to subscribe to in the session. When one client initiates the 'send data' command the javascript is created and sent to the push server with the command Juggernaut.send(data,channels). The push server then broadcasts the message to all clients on the selected channels.
Advanced Usage
Let's take a simple ajaxified rails app with Juggernaut - and then add it.
Controller:
def milestone_create
begin
@milestone = Milestone.new(params[:milestone])
@successful = @milestone.save
rescue
end
end
RJS (view)
if @successful
page.remove "#{@milestone.id}_milestone_view_container"
end
Now the controller with Juggernaut added:
def milestone_create
begin
@milestone = Milestone.new(params[:milestone])
@successful = @milestone.save
partial_to_string = Juggernaut.parse_string(render_to_string(:partial => "milestone"))Juggernaut.send("
createMilestone('#{partial_to_string}','#{cookies[:_session_id]}')
", session[:juggernaut_channels])
rescue
"alert('Request failed');"
end
end
Add some javascrip to application.js:
function createMilestone(data, ses_id) {
if (getCookie('_session_id') != ses_id) {
new Insertion.Top('milestone_list', data);
}
}
Juggernaut Helpers
As you can see, Juggernaut provides some helper methods to easily parse strings from 'render_to_string' etc.
Juggernaut.parse_string(string)
This takes a string, usually a rendered partial. It then escapes the string, and parses it onto one line so it's understood by JavaScript.
Juggernaut.string_escape(string)
This does exactly what it says on the tin, escapes a string (not url encoding).
Juggernaut.html_escape(string)
Same as the rails helper h().
Juggernaut.html_and_string_escape(string)
Just combines the two methods above - usefull for chats.
