Це простіше, ніж я спочатку думав. В основному у вас є сторінка, яка нічого не робить, поки дані, які ви хочете надіслати, не стануть доступними (скажімо, надійде нове повідомлення).
Ось справді основний приклад, який надсилає просту рядок через 2-10 секунд. 1 з 3 шанс повернення помилки 404 (щоб відобразити обробку помилок у наступному прикладі Javascript)
msgsrv.php
<?php
if(rand(1,3) == 1){
/* Fake an error */
header("HTTP/1.0 404 Not Found");
die();
}
/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>
Примітка. За допомогою справжнього сайту, запуск цього на звичайному веб-сервері, наприклад Apache, швидко зв’яже всі "робочі потоки" і не зможе відповідати на інші запити. Існують способи, але рекомендується писати «довгий-опитування сервера» в ніж - то , як в Python кручена , яка не спирається на одну нитку на запит. cometD - популярний (який доступний кількома мовами), а Tornado - це нова рамка, створена спеціально для таких завдань (вона була побудована за кодом довгострокового опитування FriendFeed) ... але, як простий приклад, Apache є більш ніж адекватним ! Цей сценарій легко можна писати будь-якою мовою (я вибрав Apache / PHP, оскільки вони дуже поширені, і мені траплялося запускати їх локально)
Потім у Javascript ви запитуєте вказаний вище файл ( msg_srv.php
) і чекаєте відповіді. Коли ви отримуєте його, ви дієте на дані. Потім ви запитуєте файл і знову зачекаєте, дійте на дані (і повторіть)
Далі йде приклад такої сторінки. Коли сторінка завантажується, вона надсилає початковий запит на msgsrv.php
файл .. Якщо це вдасться, ми додаємо повідомлення до #messages
div, то через 1 секунду ми знову викликаємо функцію waitForMsg, що запускає очікування.
1 секунда setTimeout()
- це дійсно базовий обмежувач швидкості, він справно працює без цього, але якщо msgsrv.php
завжди повертається миттєво (наприклад, із синтаксичною помилкою) - ви заливаєте браузер і він може швидко застигнути. Це краще зробити, перевіривши, чи файл містить дійсну відповідь JSON, та / або підтримує загальну кількість запитів за хвилину / секунду та робить відповідну паузу.
Якщо сторінка помилка, вона додає помилку до #messages
діва, чекає 15 секунд, а потім повторює спробу (ідентично тому, як ми чекаємо 1 секунду після кожного повідомлення)
Приємна річ у цьому підході - він дуже стійкий. Якщо клієнтське підключення до Інтернету відмирає, воно закінчиться, а потім спробуйте повторно підключитися - це властиво тому, як довго працює опитування, не потрібне складне обробка помилок
У будь-якому випадку, long_poller.htm
код, використовуючи рамку jQuery:
<html>
<head>
<title>BargePoller</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
body{ background:#000;color:#fff;font-size:.9em; }
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.old{ background-color:#246499;}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
$.ajax({
type: "GET",
url: "msgsrv.php",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:50000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
waitForMsg, /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
waitForMsg, /* Try again after.. */
15000); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
</script>
</head>
<body>
<div id="messages">
<div class="msg old">
BargePoll message requester!
</div>
</div>
</body>
</html>