views:

1476

answers:

11
+8  Q: 

Ajax polling.

In the project i am currently working on, we have the need to develop a web chat application, not a very complex chat, just a way to connect two people to talk about a very specific topic, we don't need any kind of authentication for one of the two users, we don't have to support emoticons, avatars, or stuff like that.

Some project members suggested that we could use XMPP through BOSH, I said that is like trying to catch a fish with a boat's net, and proposed a more simpler method, like a simple Ajax/MySQL web chat, but we're worried about the performance hit in the server because of the constant polling of many chats open at the same time.

Has anyone done something like this before? What would you recommend?

+3  A: 

What would you recommend?

XMPP through BOSH

There's no need to invent your own message format and transport protocol when somebody else has. If you try, it'll slowly grow to be just as complex as BOSH but without the benefit of third-party library support or standardization.

John Millikin
+4  A: 

You might also want to look into Comet.

It's used by GTalk, Meebo, and many other chat applications. A few years ago when I was experimenting with it, there weren't very many libraries or details about server architecture to implement it, but it looks like there is a lot more stuff out now.

Have a look at the cometd project for more technical information.

Ryan Guest
A: 

I thought everyone used cometd for this sort of thing.

hoyhoy
+1  A: 

You might also want to look into Comet.

I thought everyone used cometd for this sort of thing.

BOSH is a standard for transporting XMPP over HTTP. It involves Comet for pushing data to the client.

John Millikin
A: 

I did this very same thing a few months back and had fun just playing around with the concepts. I actually used the forever-frame technique instead of polling.

The below code is my "comet" js file that contains the general concepts required to get a "party chat" setup.

function Comet(key) {

  var random = key;
  var title = 'Comet';
  var connection = false;
  var iframediv = false;
  var browserIsIE = /*@cc_on!@*/false;
  var blurStatus = false;
  var tmpframe = document.createElement('iframe');
  var nl = '\r\n';

  this.initialize = function() {
    if (browserIsIE) {
      connection = new ActiveXObject("htmlfile");
      connection.open();
      connection.write("<html>");
      connection.write("<script>document.domain = '"+document.domain+"'");
      connection.write("</html>");
      connection.close();
      iframediv = connection.createElement("div");
      connection.appendChild(iframediv);
      connection.parentWindow.comet = comet;
      iframediv.innerHTML = "<iframe id='comet_iframe' src='./comet.aspx?key="+random+"'></iframe>";
    } else {
      connection = document.createElement('iframe');
      connection.setAttribute('id', 'comet_iframe');
      iframediv = document.createElement('iframe');
      iframediv.setAttribute('src', './comet.aspx?key='+random);
      connection.appendChild(iframediv);
      document.body.appendChild(connection);
    }
  }

  // this function is called from the server to keep the connection alive
  this.keepAlive = function () {
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  // this function is called from the server to update the client
  this.updateClient = function (value) {
    var outputDiv = document.getElementById('output');
    outputDiv.value = value + nl + outputDiv.value;
    if (blurStatus == true) {
        document.title = value;
    }
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  this.onUnload = function() {
    if (connection) {
      // this will release the iframe to prevent problems with IE when reloading the page
      connection = false;
    }
  }

  this.toggleBlurStatus = function(bool) {
    blurStatus = bool;
  }

  this.resetTitle = function() {
    document.title = title;
  }

  function mozillaHack() {
    // this hack will fix the hour glass and loading status for Mozilla browsers
    document.body.appendChild(tmpframe);
    document.body.removeChild(tmpframe);
  }
}
Toran Billups
is this technique rquired to have tomcat add on third-on comet library ..etc ? or can be serve on typical servlet? is there any demo /working app we can refer to?
cometta
can show us example of comet.aspx ?
cometta
This technique doesn't require anything beyond IIS6 and .NET to get up and running.
Toran Billups
A: 

I agree with John. But there was another question that was not answered.
I have done this but instead of using a database we used a flat file, it did eventually cripple the server, but it wasn't until we has ~450 active users, and if we had done it with a database it probably would have fared better.
This was done on a basic hosting account from Godaddy.

Edit: BTW Godaddy sounded less then amused when I got the phone call.

Unkwntech
A: 

I think polling is the simplest approach and would recommend that first. If the load becomes a problem start, looking into more complicated techniques. A good discussion on the pros and cons are here - http://www.infoq.com/news/2007/07/pushvspull
http://ajaxian.com/archives/a-report-on-push-versus-pull

Jimmy
+2  A: 

There is a very good server for handling message pushing from server to browser (dubbed Comet) - Orbited. It's easily integrated with other technologies (Django, Rails, PHP etc.) just like memcached.

You really should check it if you want to handle serious load. Otherwise, simple Ajax polling is the best way.

zuber
+1  A: 

The trick is to realise that the only time your app needs to invoke CGI on the server is when someone says something. For the regular polls, poll a static page that your CGI script updates whenever there is new chat. Use HEAD requests, compare the timestamps with those last seen, and only do a full GET when those change. I have a simple naive chat application implemented this way, and the load and bandwidth usage is negligible for the few tens of simultaneous users we have.

moonshadow
+3  A: 

If you don't like the idea of HTTP-polling, you could have a Flash-movie on the chat page that has a constant connection to some deamon on the server, the Flash-movie would then invoke JavaScript functions on the client to update the chat as new messages comes along. (Unless you want a Flash interface for your chat..)

svinto
A: 

Checkout Speeqe. Its a open-source solution for Web-based chat rooms that uses BOSH and XMPP behind the scenes.

melo