views:

1263

answers:

5

I need to make a chatroom for my Rails app. Are there any good tutorials for writing one? Will it be a non-Rails technology that I simply plug in or are there some Rails libraries that are meant for it?

I want to save each message to my PostgresQL database, and I want all previous messages to be visible - a perpetual chatroom.

+5  A: 

Here's a tutorial that might help you:

http://www.urubatan.info/2007/10/a-cool-chat-example-created-with-ruby-on-rails-and-juggernaut/

David Brown
+7  A: 

For logging (without searching), appending to a flat file is fine. The overhead of a database isn't worth it, and it's easy enough to parse the textfile into a database later, if you need.

As for the actual chat-room part, I would start with a simple database table, an <input> and a div to display the messages.

Get that working (no fancy updating), then use Javascript (or one of the Javascript frameworks, I'd recommend jQuery) to clear the chat <div>, grab the last 10 messages and display them in the chat div (every 20 seconds, say)

Then try and append new chat messages to the div, rather than clearing it.. One way would be, grab the last 10 messages as JSON every 20 seconds, including a unique message id (autoincrement would be fine). Keep an array of received message id's. On each refresh, check if the current messages id is in the array, if not, append it.

The HTML should be pretty simple, something like

<div id="chatmsgs">
</div>

Then you append within that div..

<div class="msg">
    [message content]
</div>

Using the jQuery functions getJSON and append should be all you need..

Then look into "long polling", basically you have a page that waits until new data before sending any content. You request this like a regular AJAX'y XmlHttpRequest, but rather than requesting the URL every x seconds, getting a blank page, you request the page once, and the page load only completes when a new message arrives. When you get data (or the connection times out), you deal with it, and wait again.. My answer (err, and question) "Simple "Long Polling" example code?" might explain it better.. The problem with long-polling is it quickly ties up all worker-thread based

Or, you could cheat and use Juggernaut (a perfectly reasonable solution)

dbr
A: 

Check out my github chat_sandbox.

Also, there are some write ups on my blog tutorials at SlightlyCoded

Or you could just hire me to do it for/with you $)

taelor
A: 

Someone's done all the hard work for you: check out Juggernaut.

It pushes messages to the clients, instead of a typical refresh every few seconds approach. It does require the client to have Flash though, but that might not be an issue in your case.

Jaryl
+1  A: 

I don't know of an existing library for something like that, but I would recommend against long polling with Ruby on Rails. DHH has written about how they went with Rails Metal for the chat polling used on CampFire, their group chat program. The downside with long polling is that it would take over a Rails process for the entirety of the request, which means your user limit would be dependent on how many rails mongrels you're running (or in the case of Passenger, how it would be severely limited).

If you create the read and write operations with Rails Metal though, it'd be very fast.

Now, if you're wanting something much more realtime, then something with XMPP and BOSH might work. This uses the long polling technique mentioned above (roughly), but the connection is to an XMPP server rather than a Rails process. The moment someone sends a message the others in the chat would get it without polling. The downside is this would be a lot more complicated (weeks to implement if you've never touched XMPP; rather than just hours to implement the Rails Metal solution). If you do go with BOSH though, Strophe is awesome and Speeqe is a sample app for it (but in Python ;/).

Rails Metal works for Campfire, and it's the easiest way to do it, so I'd go that route.

AdamFortuna