Aktualizacja
Ponieważ nadal otrzymuję opinie na ten temat, myślę, że rozsądnie jest pamiętać, że ta odpowiedź ma 4 lata. Sieć rozwija się w naprawdę szybkim tempie, więc proszę uważaj na tę odpowiedź.
Ostatnio miałem ten sam problem i szukałem informacji na ten temat.
Podane rozwiązanie nazywa się długim odpytywaniem. Aby poprawnie z niego korzystać, należy upewnić się, że żądanie AJAX ma „duży” limit czasu i zawsze wysyłać to żądanie po bieżącym zakończeniu (limit czasu, błąd lub sukces).
Long Polling - Klient
Tutaj, aby kod był krótki, użyję 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);
}
Ważne jest, aby pamiętać, że (z dokumentów jQuery ):
W jQuery 1.4.xi niższych obiekt XMLHttpRequest będzie w niepoprawnym stanie, jeśli upłynie limit czasu żądania; dostęp do dowolnego elementu obiektu może spowodować wyjątek. Tylko w przeglądarce Firefox 3.0+ żądania skryptu i żądania JSONP nie mogą zostać anulowane po przekroczeniu limitu czasu; skrypt uruchomi się, nawet jeśli dotrze po upływie limitu czasu.
Długie odpytywanie - serwer
Nie jest w żadnym konkretnym języku, ale wyglądałoby to tak:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Tutaj hasTimedOut
upewni się, że Twój kod nie czeka wiecznie, i anythingHappened
sprawdzi, czy jakieś zdarzenie się wydarzyło. Ma sleep
to na celu uwolnienie twojego wątku do robienia innych rzeczy, gdy nic się nie dzieje. events
Powróci słownika zdarzeń (lub jakiekolwiek inne struktury danych może wolisz) w formacie JSON (lub innego wolisz).
To z pewnością rozwiązuje problem, ale jeśli martwisz się skalowalnością i wydajnością, tak jak ja podczas badań, możesz rozważyć inne rozwiązanie, które znalazłem.
Rozwiązanie
Użyj gniazd!
Po stronie klienta, aby uniknąć problemów ze zgodnością, użyj socket.io . Próbuje używać gniazda bezpośrednio i ma awarie innych rozwiązań, gdy gniazda nie są dostępne.
Po stronie serwera utwórz serwer za pomocą NodeJS (przykład tutaj ). Klient zasubskrybuje ten kanał (obserwator) utworzony za pomocą serwera. Za każdym razem, gdy trzeba wysłać powiadomienie, jest ono publikowane na tym kanale, a subskrybor (klient) zostaje powiadomiony.
Jeśli nie podoba ci się to rozwiązanie, wypróbuj APE ( Ajax Push Engine ).
Mam nadzieję, że pomogłem.