Private Chat Room in Ruby on Rails 3.0

On December 5, 2010, in Technical, by Prabhat Gupta

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.conf

4.  Install juggernaut

git clone git://github.com/maccman/juggernaut.git --recursive
cd juggernaut
sudo node server.js

Till 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 chatclient

6. To enable publishing by Juggernaut

sudo gem install juggernaut

7. run rails server

rails server

open 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 defined

In 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
	});

 

Tagged with: