Как проверить наличие обновлений без использования setInterval / timeout?

создание социальной сети, я пытаюсь получить живые уведомления. В настоящее время сайт отправляет запрос AJAX каждые несколько секунд с помощью setInterval. Это выглядит примерно так:

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);

Это отлично работает, но я очень беспокоюсь о том, что создание перегрузки серверов. Я попробовал метод кометы, но по какой-то причине он отправляет гораздо больше запросов, чем приведенный выше код. Есть ли другой более полезный метод для передачи этих данных в реальном времени?

изменить: Для реализуя длинный опрос, я использовал следующее (использовал пример, упомянутый здесь: 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
    });
})();

есть вероятность, что я не смогу правильно понять принцип кометы.

PHP код:

// 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
}

поскольку Facebook также использует PHP, как они это делают?

2 ответов


вы должны использовать websockets. Вы можете подключиться к серверу и зарегистрировать обработчик onmessage. Всякий раз, когда сервер имеет что-либо для отправки клиенту, ваш обработчик будет вызван. Тайм-аут не требуется.

Проверьте поддержку websocket в вашем браузере. На данный момент их поддерживают только Chrome, Opera и Safari.

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*/
}

подключение

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

обработчики

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);
}

документация: http://www.developerfusion.com/article/143158/an-introduction-to-websockets/


Websockets будет способом пойти, как только они будут более универсально реализованы в основных браузерах - я бы предположил, как минимум 5 лет.

последнее, что я слышал Facebook чат использует comet и целую кучу серверов. Если вы хотите что-то более легкое, я могу придумать два варианта.

  1. уменьшить интервал опроса. Строго говоря, это проблема интерфейса - пользователи могут иметь вполне приемлемый опыт с интервалами до нескольких минут. Этот единственный способ узнать наверняка - это тестирование пользователя, но опрос каждые 5 секунд, вероятно, излишен. Независимо от того, что вы выбираете в качестве оптимального интервала, это дает вам быстрый способ масштабирования, если вы получаете удар - просто проверните интервал, пока серверы не перестанут плавиться.

  2. использовать кэширование проверки HTTP. Вы можете сделать запросы более легкими, если сервер возвращает тело ответа только тогда, когда содержимое изменилось с момента последнего запроса. У вас будет чтобы создать что-то пользовательское, используя ETag или последние измененные заголовки и облегченную систему проверки изменений на сервере, но это может сэкономить вам несколько байтов.