jQuery Long Polling (With PHP server side) jQuery Long Polling (With PHP server side) ajax ajax

jQuery Long Polling (With PHP server side)


You must be sure that the function terminates inside a reasonable time. What you could do is this:

$ttl = 10;while ($ttl--) {    $json = Yii::app()->user->getNotifications();    if (null != $json) {        break;    }    sleep(1);}if (null == $json) {    $json = json_encode(array(        'nothing' => true    ));}header('Content-Type: application/json');echo $json;Yii::app()->end();return;

You set up the polling function as a timer using setInterval(). The function will now be called every, say, 10 seconds, and you may need to set up a semaphore to avoid it being called before the previous iteration has returned:

var timer = setInterval(    function() {        if (this.calling) {            return;        }        var fn = this;        fn.calling = true;        $.post(url)         .done(function(data) {            ..         })         .always(function() {            fn.calling = false;         });    },    10000);

Then the polling function in AJAX needs to check (in the .done()) callback) that the notification is there:

function(data) {    if (data.hasOwnProperty('nothing')) {        alert('No notifications');        return;    }    console.log(data);    ...}

Now one important thing is what does your notification look like. Here I've assumed it is a JSON encoded string. But if it is an array or object that the Yii function returns instead, you need to handle its encoding. This might be even cleaner, without any IF's:

header('Content-Type: ...die(json_encode(    array(        'status'         => 'success',        'notification'   => $json /* This is NULL or an array */    )    // Javascript side we check that data.notification is not null.));

The decoding is already handled by jQuery, so the variable "data" above will already be a Javascript object, and you need not call JSON.parse. You can check that data is an object though, and that it has the expected properties. That will warn you of any errors.

To handle the navigation to another page, you can store the setInterval()-supplied timer ID of the polling Javascript function in a global variable, and delete the timer when the page calls onUnload() to deactivate the polling.


What does the getNotifications return if there are no notifications? jQuery expects an JSON format to be returned but when you just echo an empty string the request fails as the format of the response is not a JSON. Make sure to echo JSON string everytime.


How about this. I assume the $.(get) is in a function called notificationPoll(); which is re-called once completed.

$.ajax({    url: event_feed_href,    async: false,    timeout: 60000,    done: function(data) {            var got_json=false;            try {                var json = JSON.parse(data);                got_json=true;            }            catch(e) {                // failed to return JSON data                alert('Wierd!');            }             if(got_json) {                // process json data                alert('New Notification!');            }        },    always: function() {            notificationPoll();        }    });

I've used done and always here as jQuery says is depreciating success: fail: