Это проще, чем я думал вначале. По сути, у вас есть страница, которая ничего не делает, пока не будут доступны данные, которые вы хотите отправить (скажем, приходит новое сообщение).
Вот действительно простой пример, который отправляет простую строку через 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
div, ждет 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>
sleep(rand(2,10));
? чтобы ничего не делать, опрашивать базу каждые 100 милисек? когда он решает умереть?У меня есть очень простой пример чата как часть болтовни .
Изменить : (так как каждый вставляет свой код здесь)
Это полный многопользовательский чат на основе JSON с использованием длинных опросов и слоша . Это демонстрация того, как выполнять вызовы, поэтому, пожалуйста, игнорируйте проблемы XSS. Никто не должен использовать это без предварительной дезинфекции.
Обратите внимание, что клиент всегда имеет соединение с сервером, и как только кто-то отправляет сообщение, каждый должен увидеть его примерно мгновенно.
источник
getNewComments
обратным вызовом, поэтому он просто бесконечно запускает его в конце каждого ajax-запросаTornado предназначен для длинных опросов и включает в себя очень небольшое (несколько сотен строк Python) приложение чата в / examples / chatdemo , включая код сервера и код клиента JS. Это работает так:
Клиенты используют JS для запроса обновлений, поскольку (номер последнего сообщения) сервер URLHandler получает их и добавляет обратный вызов, чтобы ответить клиенту в очередь.
Когда сервер получает новое сообщение, событие onmessage срабатывает, перебирает обратные вызовы и отправляет сообщения.
JS на стороне клиента получает сообщение, добавляет его на страницу, а затем запрашивает обновления с этого нового идентификатора сообщения.
источник
Я думаю, что клиент выглядит как обычный асинхронный AJAX-запрос, но вы ожидаете, что для его возврата потребуется «много времени».
Сервер выглядит следующим образом.
Итак, AJAX-запрос отправляется на сервер, возможно, с отметкой времени последнего обновления, чтобы вы
hasNewData()
знали, какие данные вы уже получили. Сервер затем зацикливается, пока не появятся новые данные. Все это время ваш AJAX-запрос все еще подключен, просто висит там в ожидании данных. Наконец, когда новые данные доступны, сервер передает их на ваш AJAX-запрос и закрывает соединение.источник
Вот некоторые классы, которые я использую для длинного опроса в C #. Есть в основном 6 классов (см. Ниже).
источник
Это хороший 5-минутный скринкаст о том, как сделать длинный опрос с использованием PHP и jQuery: http://screenr.com/SNH
Код очень похож на приведенный выше пример dbr .
источник
Вот простой пример длинного опроса в PHP от Эрика Дуббелбоера с использованием
Content-type: multipart/x-mixed-replace
заголовка:И вот демо:
http://dubbelboer.com/multipart.php
источник
Я использовал это, чтобы разобраться с Comet, я также настроил Comet, используя сервер Java Glassfish, и нашел много других примеров, подписавшись на cometdaily.com.
источник
Посмотрите на это сообщение в блоге, в котором есть код для простого приложения чата в Python / Django / gevent .
источник
Ниже приведено длинное решение для опроса, которое я разработал для Inform8 Web. По сути, вы переопределяете класс и реализуете метод loadData. Когда loadData возвращает значение или время ожидания операции будет напечатано, результат вернется.
Если обработка вашего скрипта может занять более 30 секунд, вам может потребоваться изменить вызов set_time_limit () на что-то более длинное.
Лицензия Apache 2.0. Последняя версия на github https://github.com/ryanhend/Inform8/blob/master/Inform8-web/src/config/lib/Inform8/longpoll/LongPoller.php
Райан
источник
Спасибо за код, дбр . Просто небольшая опечатка в long_poller.htm вокруг строки
Я думаю, что это должно быть
чтобы это работало.
Для тех, кто заинтересован, я попробовал эквивалент Django. Начните новый проект Django, скажите lp для длительного опроса:
Вызовите приложение msgsrv для сервера сообщений:
Добавьте следующие строки в settings.py, чтобы иметь каталог шаблонов :
Определите ваши шаблоны URL в urls.py следующим образом:
И msgsrv / views.py должен выглядеть так:
Наконец, templates / long_poller.htm должен быть таким же, как указано выше, с исправленной опечаткой. Надеюсь это поможет.
источник
"15000"
это синтаксическая ошибка. setTimeout принимает целое число в качестве второго параметра.Это один из сценариев, для которых PHP является очень плохим выбором. Как упоминалось ранее, вы можете очень быстро связать всех своих работников Apache, выполнив что-то подобное. PHP построен для запуска, выполнения, остановки. Он не создан для запуска, подождите ... выполните, остановите. Вы очень быстро отключите свой сервер и обнаружите, что у вас невероятные проблемы с масштабированием.
Тем не менее, вы все равно можете сделать это с помощью PHP, и он не убьет ваш сервер с помощью nginx HttpPushStreamModule: http://wiki.nginx.org/HttpPushStreamModule
Вы устанавливаете nginx перед Apache (или чем-то еще), и он позаботится о том, чтобы удерживать открытыми параллельные соединения. Вы просто отвечаете полезной нагрузкой, отправляя данные на внутренний адрес, который вы можете сделать с помощью фонового задания, или просто отправляете сообщения людям, которые ждали, когда поступают новые запросы. Это не позволяет процессам PHP оставаться открытыми во время длительного опроса.
Это не только для PHP и может быть сделано с помощью nginx с любым языком бэкэнда. Загрузка одновременных открытых соединений равна Node.js, поэтому самый большой плюс в том, что он вытаскивает вас из узла NEEDING для чего-то подобного.
Вы видите много других людей, которые упоминают другие языковые библиотеки для выполнения длинных опросов, и это не без причины. PHP просто не очень хорошо подходит для такого поведения.
источник
Почему бы не рассмотреть веб-сокеты вместо длинного опроса? Они очень эффективны и просты в настройке. Однако они поддерживаются только в современных браузерах. Вот краткий справочник .
источник
Группа WS-I опубликовала нечто, называемое «Надежный безопасный профиль» , в котором реализована реализация Glass Fish и .NET, которая, по - видимому, хорошо взаимодействует .
Если повезет, есть также реализация Javascript .
Существует также реализация Silverlight, которая использует HTTP Duplex. Вы можете подключить javascript к объекту Silverlight, чтобы получать обратные вызовы, когда происходит push.
Есть также коммерческие платные версии .
источник
Для реализации ASP.NET MVC посмотрите на SignalR, который доступен на NuGet . Обратите внимание, что NuGet часто устарел из источника Git, который получает очень частые коммиты.
Узнайте больше о SignalR в блоге Скотта Хансельмана
источник
Вы можете попробовать icomet ( https://github.com/ideawu/icomet ), кометный сервер C1000K C ++, созданный с libevent. icomet также предоставляет библиотеку JavaScript, ее легко использовать так же просто, как
icomet поддерживает широкий спектр браузеров и операционных систем, включая Safari (iOS, Mac), IE (Windows), Firefox, Chrome и т. д.
источник
Простейший NodeJS
Мудрый сценарий производства в Express, например, вы можете получить
response
в промежуточном программном обеспечении. Делаете ли вы то, что вам нужно сделать, можете охватить все методы с длительным опросом для Map или чего-либо (что видно другим потокам) и вызывать<Response> response.end()
всякий раз, когда вы будете готовы. В длинных опросах нет ничего особенного. Отдых - это то, как вы обычно структурируете свое приложение.Если вы не знаете, что я имею в виду, подмечая, это должно дать вам представление
Как видите, вы могли бы действительно реагировать на все соединения, во-первых, делать все, что вы хотите. Существует
id
для каждого запроса, поэтому вы должны иметь возможность использовать карту и доступ к конкретным вне вызова API.источник