2009-06-03 16 views
12

Czy muszę odrzucić wszystkie nagłówki HTTP, aby poinformować przeglądarkę, że mój serwer nie będzie natychmiastowo zamykać połączenia i wyświetlać jako otrzymany kod HTML? Czy jest coś, co konieczne, aby HTML był wyświetlany przyrostowo, jak flush()?Jak wyświetlać HTML do przeglądarki przyrostowo przez dłuższy czas?

Ta technika była używana do takich celów, jak czat, ale myślę o używaniu go do aplikacji typu COMET.

Odpowiedz

14

Long polling to powszechna technika, aby zrobić coś takiego; krótko podsumowując, działa następująco:

  1. Klient wysyła XHR na serwer.

    • Jeśli są gotowe dane, serwer natychmiast to zwraca.
    • Jeśli nie, serwer utrzymuje połączenie otwarte, dopóki dane nie będą dostępne, następnie zwraca to.
    • Jeśli upłynął limit czasu żądania, wróć do 1).
  2. Strona działająca na kliencie odbiera te dane i robi to, co z nimi robi.

  3. Wróć do 1)

ten sposób Facebook implements its chat feature.

This article wyjaśnia również niektóre z błędnych koncepcji długiego głosowania i podaje niektóre z korzyści płynących z tego.

+0

Tego właśnie szukałem, pomimo faktu, że tytuł pytania jest zawikłany. – cgp

+0

Z pewnością działa z Facebookiem - powiadomienia, czat i wiele innych funkcji działa przy użyciu tej metody. –

+2

Trzymaj się mojego Facebooka używa Erlanga na zapleczu do obsługi czatu, aby mógł zarządzać wszystkimi otwartymi połączeniami. Apache/PHP nigdy nie byłby w stanie skalować tak wysoko. –

0

W zależności od tego, co robisz, możesz po prostu wywołać echo, gdy twój skrypt zacznie działać, to następnie wyśle ​​kod HTML do przeglądarki, ponieważ jest odtwarzana echem.

1

Myślę, że bardziej niezawodnym rozwiązaniem jest strona z zegarem JavaScript, który sprawdza serwer w poszukiwaniu nowych danych. Pozostawienie otwartej odpowiedzi nie jest czymś, do czego został zaprojektowany protokół HTTP.

+0

Po opublikowaniu mojej koperty zobaczyłem, że zdecydowanie jest to lepsza odpowiedź. Możesz po prostu mieć DIV, który wypełniasz materiałami AJAX używając JavaScript. – bdwakefield

+0

być bardzo złym rozwiązaniem dla czegoś takiego jak czat, gdzie przerwy mogą się bardzo różnić i chcesz, aby odpowiedzi pojawiały się szybko y, ale jednocześnie unikaj obciążania serwera częstymi sondażami przez tysiące klientów, którzy nie zwracają niczego przez większość czasu. Używanie protokołu HTTP do czegoś, co nie zostało zaprojektowane do pracy i jest lepszym rozwiązaniem w takim przypadku. –

1

Chciałbym po prostu echo/wydrukować HTML, jak poszedłem. Istnieje kilka różnych sposobów na zatrzymanie skryptu przed wysłaniem następnego. Nie musisz nic robić z nagłówkami lub specjalnym kodem, aby zachęcić przeglądarkę do oczekiwania. Dopóki skrypt nadal działa, renderuje kod HTML otrzymany ze skryptu.

echo "<HTML><HEAD.../HEAD><BODY>"; 
while (running) 
{ 
    echo "printing html... </br>"; 
} 
echo "</BODY></HTML>"; //all done 
0

Proponuję, abyś zbadał implementację takiej funkcjonalności za pomocą Ajax, zamiast zwykłego starego HTML. Zapewnia to o wiele większą elastyczność w zakresie projektowania architektonicznego i interfejsu użytkownika

2

Klient zamknie połączenie, gdy nie otrzyma żadnych danych przez określony czas. Na ten limit czasu nie mają wpływu nagłówki HTTP. Jest to specyficzne dla klienta i zwykle jest ustawione na 120 sekund IIRC.

Wszystko, co musisz zrobić, to regularnie wysyłać niewielkie ilości danych, aby uniknąć przekroczenia limitu czasu.

1

Przymierz zawsze ramki (jak w Gmailu)

Wszystkie te techniki są właśnie hacki http nie jest przeznaczony do tego celu.

1

na końcu skryptu, należy użyć coś takiego (zakładając, trzeba było wyjścia buforowane przez umieszczenie ob_start() w górnej części strony

<?php 

set_time_limit(0); // Stop PHP from closing script after 30 seconds 

ob_start(); 

echo str_pad('', 1024 * 1024, 'x'); // Dummy 1 megabyte string 

$buffer = ob_get_clean(); 

while (isset($buffer[0])) { 

$send = substr($buffer, 0, 1024 * 30); // Get 30kbs bytes from buffer :D 
$buffer = substr($buffer, 1024 * 30); // Shorten buffer 

echo $send; // Send buffer 
echo '<br />'; // forces browser to reload contents some how :P 

ob_flush(); // Flush output to browser 
flush(); 

sleep(1); // Sleep for 1 second 

} 

?> 

Że skrypt po prostu wyjść 1 megabajta tekstu w 30kbs (symulowane) bez względu na szybkość połączenia użytkownika i serwera:

Powiązane problemy