2
votes

I've made a simple PHP jQuery Chat Application with Short Polling (AJAX Refresh). Like, every 2 - 3 seconds it asks for new messages. But, I read that Long Polling is a better approach for Chat applications. So, I went through some Long Polling scripts. I made like this:

Javascript:

$("#submit").click(function(){
    $.ajax({
        url: 'chat-handler.php',
        dataType: 'json',
        data: {action : 'read', message : 'message'}
    });
});

var getNewMessage = function() {
    $.ajax({
        url: 'chat-handler.php',
        dataType: 'json',
        data: {action : 'read', message : 'message'},
        function(data){
            alert(data);
        }
    });

    getNewMessage();
}

$(document).ready(getNewMessage);

PHP

<?php
    $time = time();
    while ((time() - $time) < 25) {
        $data = $db->getNewMessage ();

        if (!empty ($data)) {
            echo json_encode ($data);
            break;
        }

        usleep(1000000); // 1 Second
    }
?>

The problem is, once getNewMessage() starts, it executes unless it gets some response (from chat-handler.php). It executes recursively. But if someone wants to send a message in between, then actually that function ($("#submit").click()) never executes as getNewMessage() is still executing. So is there any workaround?

2

2 Answers

5
votes

I strongly recommend that you read up on two things: the idea behind long polling, and jQuery callbacks. I'll quickly go into both, but only in as much detail as this box allows me to.

Long polling

The idea behind long polling is to have the webserver artificially "slow down" when returning the request so that it waits until an event has come up, and then immediately gives the information, and closes the connection. This means that your server will be sitting idle for a while (well, not idle, but you know what I mean), until it finally gets the info that a message went through, sends that back to the client, and proceeds to the next one.

On the JS client side, the effect is that the Ajax callback (this is the important bit) is delayed.

jQuery .ajax()

$.ajax() returns immediately. This is not good. You have two choices to remedy this:

  • bind your recursion call in the success and error callback functions (this is important. the error function might very well come up due to a timeout)
  • (see below):

Use This:

var x = $.ajax({blah});
$.when(x).done(function(a) { recursiveCallHere(); });

Both amount to the same thing in the end. You're triggering your recursion on callback and not on initiation.

P.S: what's wrong with sleep(1)?

3
votes

In long polling new request should be initiated when you have received the data from the previous one. Otherwise you will have infinite recursion in browser freezing.

var getNewMessage = function() {
    $.ajax({
        url: 'chat-handler.php',
        dataType: 'json',
        data: {action : 'read', message : 'message'},
        success: function(data) {
            alert(data);

            getNewMessage();   // <-- should be here
        }
    });
}