Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check for live updates without using setInterval/timeout?

Building a social network, I'm trying to fetch live notifications. Currently, the site sends an AJAX request every few seconds using setInterval. It looks something like this:

setInterval ( function(){
    url = base_dir+"/ajax/file.php";
    data = "data=someData";
    $.ajax({
        type: "POST",
        url: url,
        data: data,
        dataType: "json",
        beforeSend: function(x) {
            if(x && x.overrideMimeType) {
                x.overrideMimeType("application/json;charset=UTF-8");
            }
        },
        success: function(JSON){
            // retrieve data here   
        }
    });
}, 5000);

That works perfectly, but I'm very worried about that creating servers overload. I tried the comet technique but for some reason it sends much more requests than the above code. Is there any other more useful technique for pushing this data live?

EDIT: For implementing long polling I used the following (used the example mentioned here: http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery):

(function poll(){
    url = base_dir+"/ajax/file.php";
    data = "data=someData";
    $.ajax({
        type: "POST",
        url: url,
        data: data,
        dataType: "json",
        beforeSend: function(x) {
            if(x && x.overrideMimeType) {
                x.overrideMimeType("application/json;charset=UTF-8");
            }
        },
        success: function(JSON){
            // retrieve data here   
        },
complete: poll,
timeout: 5000
    });
})();

There's a possibility that I might not get the comet principle right.

PHP code:

// Checks for new notifications, and updates the title and notifications bar if there are any
 private static function NotificationsCounter (){
    //self::$it_user_id                                     = query that retrieves my id for further checks;                                                        
    //$friend_requests_count                                = query that retrieves the friend requests count;
    //$updates_count                                        = query that retrieves the updates count;               
    $total_notifications                                    = $friend_requests_count+$updates_count;

    if ($total_notifications > 0) $addToTitle = "(".$total_notifications.")";
    else $addToTitle = "";

    if ($updates_count > 0) $counterHTML = "<span class='notification_counter' id='updates_counter' style='float: right;'>".$updates_count."</span>";
    else $counterHTML = "";

    $data = array("counter"=>$total_notifications,"addToTitle"=>$addToTitle,"counterHTML"=>$counterHTML,);
    echo json_encode($data); // parse to json and print
}

Since Facebook uses PHP as well, how do they do it?

like image 566
talhof9 Avatar asked Jan 01 '13 17:01

talhof9


2 Answers

You should use websockets. You can connect to the server and register onmessage handler. Whenever the server has anything to be send to client, your handler will get invoked. No timeout needed.

Check for websocket support in your browser. As of now, only Chrome, Opera and Safari support them.

if ('WebSocket' in window){
   /* WebSocket is supported. You can proceed with your code*/
} else {
   /*WebSockets are not supported. Try a fallback method like long-polling etc*/
}

Connecting

var connection = new WebSocket('ws://example.org:12345/myapp');

Handlers

connection.onopen = function(){
   console.log('Connection open!');
}

connection.onclose = function(){
   console.log('Connection closed');
}

connection.onmessage = function(e){
   var server_message = e.data;
   console.log(server_message);
}

Documentation: http://www.developerfusion.com/article/143158/an-introduction-to-websockets/

like image 89
ATOzTOA Avatar answered Nov 02 '22 21:11

ATOzTOA


Websockets will be the way to go once they are more universally implemented across the major browsers - I would guess a minimum of 5 years.

The last I heard Facebook chat uses comet and a whole bunch of servers. If you want something more lightweight I can think of two options.

  1. Reduce the polling interval. This is strictly a UI issue - users may have a perfectly acceptable experience with intervals as long as a couple minutes. The only way to know for certain is through user testing, but polling every 5 seconds is probably overkill. No matter what you choose as the optimal interval, this does give you an quick way to scale if you are getting hammered - just crank up the interval until the servers stop melting.

  2. Use HTTP validation caching. You can make the requests more lightweight if the server only returns a response body when the content has changed since the last request. You will have to build something custom using ETag or Last-Modified headers and a lightweight modification checking system on the server, but it might save you a few bytes.

like image 45
Chris Broski Avatar answered Nov 02 '22 22:11

Chris Broski