Обновить
Поскольку я продолжаю получать отзывы об этом, я думаю, что разумно помнить, что этому ответу 4 года. Веб развивался очень быстрыми темпами, поэтому, пожалуйста, помните об этом ответе.
У меня недавно была та же самая проблема и исследовал предмет.
Данное решение называется длинным опросом, и для его правильного использования вы должны быть уверены, что ваш AJAX-запрос имеет «большой» тайм-аут и всегда выполнять этот запрос после окончания текущего (тайм-аут, ошибка или успех).
Длинный опрос - Клиент
Здесь, для краткости кода, я буду использовать jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (eventList) {
// Handle your data here
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data); // handle the `eventName` with `data`
}
}).always(pollTask);
}
Важно помнить, что (из документов jQuery ):
В jQuery 1.4.x и ниже объект XMLHttpRequest будет в недопустимом состоянии, если время ожидания истекло; доступ к любому члену объекта может вызвать исключение. Только в Firefox 3.0+ запросы на скрипты и JSONP не могут быть отменены тайм-аутом; скрипт будет работать, даже если он прибудет после истечения времени ожидания.
Длинный опрос - сервер
Это не на каком-то конкретном языке, но это будет примерно так:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Здесь hasTimedOut
убедитесь, что ваш код не ждет вечно, и anythingHappened
проверит, произошло ли какое-либо событие. Предназначен sleep
для освобождения вашей темы, чтобы делать другие вещи, пока ничего не происходит. events
Возвращает словарь событий (или любой другой структуры данных , вы можете предпочесть) в формате JSON (или любой другой вы предпочитаете).
Это, безусловно, решает проблему, но, если вы обеспокоены масштабируемостью и производительностью, как я это делал при исследовании, вы могли бы рассмотреть другое решение, которое я нашел.
Решение
Используйте розетки!
На стороне клиента, чтобы избежать проблем совместимости, используйте socket.io . Он пытается использовать сокет напрямую и иметь запасные варианты для других решений, когда сокеты недоступны.
На стороне сервера создайте сервер, используя NodeJS (пример здесь ). Клиент подпишется на этот канал (наблюдатель), созданный на сервере. Всякий раз, когда необходимо отправить уведомление, оно публикуется на этом канале, и подписчик (клиент) получает уведомление.
Если вам не нравится это решение, попробуйте APE ( Ajax Push Engine ).
Надеюсь, я помог.