This sample will let you develop a private chatRoom using juggernaut. It push chats in realtime based on publish/subscribe model, hence making it extremely fast and scalable.
- Resources
Nodejs – http://nodejs.org/
Redis – http://code.google.com/p/redis/
Juggernaut – https://github.com/maccman/juggernaut/
JQuery – http://mirror.ozdiy.com/assets/b8/2f96a12bc919b37e09d303b86ea1b9_1251811910.html
- Getting started
1. Install node-v0.2.5 – Download
2. Install redis 2.0.4 – Download
3. Run Redis server
./redis-server redis.conf4. Install juggernaut
git clone git://github.com/maccman/juggernaut.git --recursive
cd juggernaut
sudo node server.jsTill this point, you would have all things in place except that juggernaut would still not be able to publish chats onto channels. This feature will get enabled after Step#5
5. Now you are ready to implement private chat app in RoR3. To get a sample chat application:
git clone git://github.com/prabgupt/chatclient.git --recursive
cd chatclient6. To enable publishing by Juggernaut
sudo gem install juggernaut7. run rails server
rails serveropen URLS: localhost:3000/chat/channel1
localhost:3000/chat/channel2
channel1 and channel2 are assumed to be two users in this application who are trying to chat.
- In case you are interested to build your own app from scratch
Install jquery inside your application first before getting started
rails plugin install git://github.com/aaronchi/jrails.git
copy the javascript files in the plugin folder to your javascripts directory.
Develop two view html which will actually be chat windows for two different users say channel1 and channel2
Include javascripts library references
<%= javascript_include_tag 'jquery', 'application'%>
subscribe for private channel1_channel2 between users channel1 and channel2
jug.subscribe("/chats/channel1_channel2", function(data){
var li = $("<li/>");
li.text(data);
$("#mesg").append(li);
});
Add ajax enabled form:
<% form_tag('/chat/send', :id => 'chat_window', :remote => true) do %> <%= text_field_tag 'msg_body', '', :size => 50 %> <%= text_field_tag 'sender', 'channel1'%><%= submit_tag 'Send Message' %> <% end %>
In the text_field_tag above sender can be choosen dynamically based on user if in session.
Add code inside controller associated with the view to publish message to server
#chat_controller.rb
require "juggernaut"class ChatController < ApplicationController
def send_message
@messg = params[:msg_body]
@sender = params[:sender]
Juggernaut.publish(select_channel("/channel1_channel2"), parse_chat_message(params[:msg_body], params[:sender]))
respond_to do |format|
format.js
end
end
...
Sub methods’ implementation are present inside code sample. You can anyways implement those in any way you like. Just keep in mind that juggernaut publish API requires channel name as first argument and second argument as message which is to be published to channel provided before. Here you can choose the channel dynamically based on users between whom message is currently being exchanged. Also you can write logic to persist messages, if you need, inside this method of controller.
Now final step would be to send_message.js.erb file with default name ‘send_message’ inside which we will reset the text fiend values
#send_message.js.erb
$("#chat_window")[0].reset();
You can perform various other operation here where in you can update only specific portion/fields of page depending on the user interface you choose for your chat window.
You are now ready to run this application. Please note that intend of current demo application is to just show how to build a private chat app using third party plugins in ruby on rails. You can anyways enhance it based on your usage.
I have listed below few issues which I faced while building this application which are applicable for any general applicatin being developed on ruby on rails 3.0
#1 : even after running ‘sudo gem install juggernaut’, it was showing following error at line: require “juggernaut”, which was present at top of application controller
no such file to load -- juggernaut
Solution: On adding below line inside Gemfile of your project:
gem 'juggernaut', :git => 'git://github.com/maccman/juggernaut.git'
and then running ‘sudo gem install juggernaut’, the issue was gone.
#2 : On running application, javascript console was throwing below error
jQuery is not definedIn my view html, I was calling jquery before application, however in default application layout call to default javascripts library was present which was mesing things up by calling application.js before jQuery was called.
Solution: Either change default javascript libraries setting or remove/change the call for the same inside application layout generated by default.
#3 : Error:
"Property '$' of object [object DOMWindow] is not a function" at line: $(document).ready(function()
Solution: This was coming because I was using jQuery in no conflict [jQuery.noConflict();]. After removing this mode, it worked fine. Though if you want to use jQuery mode in no conflict mode, which is btw recommended, you can check this thread: http://www.sitepoint.com/forums/showthread.php?t=712582
As per it, in “no-confict” mode, the $ shortcut is not available and the longer jQuery is used. To use the default jQuery shortcut of $, you can use the following wrapper around your code:
jQuery(document).ready(function($) {
// $() will work as an alias for jQuery() inside of this function
});
