Как утверждали другие, у вас нет гарантии относительно порядка, когда вы перебираете свойства объекта. Если вам нужен упорядоченный список нескольких полей, я предложил создать массив объектов.
var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];
Таким образом вы можете использовать регулярный цикл и иметь порядок вставки. Затем вы можете использовать метод сортировки массива, чтобы отсортировать его в новом массиве, если это необходимо.
Это более просто, чем я первоначально думал.. В основном у Вас есть страница, которая ничего не делает, пока данные, которые Вы хотите отправить, не доступны (скажите, новое сообщение прибывает).
Вот действительно основной пример, который отправляет простую строку после 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 является популярным (который доступен на нескольких языках), и , Торнадо является новой платформой, сделанной специально для таких задач (это было создано для долго опрашивающего кода FriendFeed)..., но как простой пример, Apache является более, чем соответствующим! Этот сценарий мог легко быть записан на любом языке (я выбрал Apache/PHP, поскольку они очень распространены, и я, оказалось, выполнял их локально)
Затем в JavaScript, Вы запрашиваете вышеупомянутый файл (msg_srv.php
) и ожидаете ответа. Когда Вы добираетесь один, Вы реагируете на данные. Тогда Вы запрашиваете файл и ожидаете снова, реагируете на данные (и повторение)
, Что следует, пример такой страницы.. Когда страница загружается, она отправляет начальный запрос для msgsrv.php
файл.. Если это успешно выполняется, мы добавляем сообщение к #messages
отделение, то после 1 секунды мы вызываем waitForMsg функцию снова, которая инициировала ожидание.
1 секунда setTimeout()
действительно ограничитель базовой скорости, она хорошо работает без этого, но если msgsrv.php
всегда возвраты немедленно (с синтаксической ошибкой, например) - Вы лавинно рассылаете браузер, и она может быстро замерзнуть. Это было бы лучше сделано, проверив, содержит ли файл допустимый ответ JSON и/или хранение рабочего общего количества requests-per-minute/second и приостановки соответственно.
, Если ошибки страницы, это добавляет ошибку к #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>
Я использовал это для понимания с Кометой, я также настроил Комету с помощью Java сервер Glassfish и нашел много других примеров путем подписки на cometdaily.com
Я думаю, что клиент похож на нормальный асинхронный запрос Ajax, но Вы ожидаете, что он займет много времени для возвращения.
сервер тогда похож на это.
while (!hasNewData())
usleep(50);
outputNewData();
Так, запрос Ajax переходит к серверу, вероятно, включая метку времени того, когда это было последнее обновление так, чтобы Ваш hasNewData()
знал, какие данные Вы уже получили. Сервер тогда находится в цикле, спя, пока новые данные не доступны. Все время Ваш запрос Ajax все еще соединен, просто зависнув там ожидающий данных. Наконец, когда новые данные доступны, сервер дает их Вашему запросу Ajax и закрывает соединение.
У меня есть действительно простой пример чата как часть слякоть .
Редактирование : (начиная с общей вставки их кода в здесь)
Это - полный основанный на JSON многопользовательский чат с помощью длинного опроса и слякоть . Это демонстрация из как сделать вызовы, поэтому, проигнорируйте проблемы XSS. Никто не должен развертывать это, не санируя его сначала.
Уведомление, что у клиента всегда есть соединение с сервером, и как только любой отправляет сообщение, все должны видеть его примерно немедленно.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright (c) 2008 Dustin Sallings <dustin+html@spy.net> -->
<html lang="en">
<head>
<title>slosh chat</title>
<script type="text/javascript"
src="http://code.jquery.com/jquery-latest.js"></script>
<link title="Default" rel="stylesheet" media="screen" href="style.css" />
</head>
<body>
<h1>Welcome to Slosh Chat</h1>
<div id="messages">
<div>
<span class="from">First!:</span>
<span class="msg">Welcome to chat. Please don't hurt each other.</span>
</div>
</div>
<form method="post" action="#">
<div>Nick: <input id='from' type="text" name="from"/></div>
<div>Message:</div>
<div><textarea id='msg' name="msg"></textarea></div>
<div><input type="submit" value="Say it" id="submit"/></div>
</form>
<script type="text/javascript">
function gotData(json, st) {
var msgs=$('#messages');
$.each(json.res, function(idx, p) {
var from = p.from[0]
var msg = p.msg[0]
msgs.append("<div><span class='from'>" + from + ":</span>" +
" <span class='msg'>" + msg + "</span></div>");
});
// The jQuery wrapped msgs above does not work here.
var msgs=document.getElementById("messages");
msgs.scrollTop = msgs.scrollHeight;
}
function getNewComments() {
$.getJSON('/topics/chat.json', gotData);
}
$(document).ready(function() {
$(document).ajaxStop(getNewComments);
$("form").submit(function() {
$.post('/topics/chat', $('form').serialize());
return false;
});
getNewComments();
});
</script>
</body>
</html>
Thanks for the code, dbr. Just a small typo in long_poller.htm around the line
1000 /* ..after 1 seconds */
I think it should be
"1000"); /* ..after 1 seconds */
for it to work.
For those interested, I tried a Django equivalent. Start a new Django project, say lp for long polling:
django-admin.py startproject lp
Call the app msgsrv for message server:
python manage.py startapp msgsrv
Add the following lines to settings.py to have a templates directory:
import os.path
PROJECT_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, 'templates'),
)
Define your URL patterns in urls.py as such:
from django.views.generic.simple import direct_to_template
from lp.msgsrv.views import retmsg
urlpatterns = patterns('',
(r'^msgsrv\.php$', retmsg),
(r'^long_poller\.htm$', direct_to_template, {'template': 'long_poller.htm'}),
)
And msgsrv/views.py should look like:
from random import randint
from time import sleep
from django.http import HttpResponse, HttpResponseNotFound
def retmsg(request):
if randint(1,3) == 1:
return HttpResponseNotFound('<h1>Page not found</h1>')
else:
sleep(randint(2,10))
return HttpResponse('Hi! Have a random number: %s' % str(randint(1,10)))
Lastly, templates/long_poller.htm should be the same as above with typo corrected. Hope this helps.
This is a nice 5-minute screencast on how to do long polling using PHP & jQuery: http://screenr.com/SNH
Code is quite similar to dbr's example above.
Команда MS Patterns and Practices создала Enterprise Library в качестве ответа на этот вопрос для множества распространенных сценариев. EntLib включает в себя кэширование, а также доступ к данным, проверку, ведение журнала, обработку исключений и т. Д. Мы использовали его годами и не думали бы начинать новый проект без него.
http://www.codeplex.com / entlib
А также домашняя страница P&P, http://msdn.microsoft.com/en-us/practices/default.