Как проверить наличие обновлений без использования 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 и целую кучу серверов. Если вы хотите что-то более легкое, я могу придумать два варианта.
уменьшить интервал опроса. Строго говоря, это проблема интерфейса - пользователи могут иметь вполне приемлемый опыт с интервалами до нескольких минут. Этот единственный способ узнать наверняка - это тестирование пользователя, но опрос каждые 5 секунд, вероятно, излишен. Независимо от того, что вы выбираете в качестве оптимального интервала, это дает вам быстрый способ масштабирования, если вы получаете удар - просто проверните интервал, пока серверы не перестанут плавиться.
использовать кэширование проверки HTTP. Вы можете сделать запросы более легкими, если сервер возвращает тело ответа только тогда, когда содержимое изменилось с момента последнего запроса. У вас будет чтобы создать что-то пользовательское, используя ETag или последние измененные заголовки и облегченную систему проверки изменений на сервере, но это может сэкономить вам несколько байтов.