2009-06-03 3 views
12

Нужно ли мне передавать любые HTTP-заголовки, чтобы сообщить браузеру, что мой сервер не будет немедленно закрывать соединение и отображать при получении HTML-кода? Есть ли что-нибудь необходимое для того, чтобы HTML-код постепенно отображался как flush()?Как отображать HTML-код в браузере постепенно в течение длительного периода времени?

Этот метод использовался для таких вещей, как чат, но я думаю об использовании его для приложения типа COMET.

ответ

14

Long polling - обычная техника, позволяющая сделать что-то подобное; для краткого обобщения, он работает следующим образом:

  1. Клиент отправляет XHR на сервер.

    • Если данные готовы, сервер немедленно возвращает это сообщение.
    • Если нет, сервер держит соединение открытым до тех пор, пока данные не станут доступными, а затем вернет это.
    • Если запрос тайм-аута, вернитесь к 1).
  2. Страница, выполняемая на клиенте, получает эти данные и делает то, что она делает с ней.

  3. Вернуться к 1)

Это как Facebook implements its chat feature.

This article также устраняет некоторые неправильные представления о длительном опросе, а также детали некоторых преимуществ этого.

+0

Это то, что я искал, несмотря на то, что заголовок вопроса искажен. – cgp

+0

Он работает с Facebook - уведомления, чат и многие другие функции работают с использованием этого метода. –

+2

Держите в моем, что Facebook использует Erlang на бэкэнд для обработки чата, чтобы он мог управлять всеми открытыми соединениями. Apache/PHP никогда не сможет масштабировать этот максимум. –

0

В зависимости от того, что вы делаете, вы можете просто откликнуться по мере продолжения вашего сценария, после чего он отправит html в браузер, поскольку он будет эхом.

1

Я думаю, что более надежное решение - это страница с таймером Javascript, который опросит сервер для новых данных. Сохранение ответа открытым - это не то, для чего был разработан протокол HTTP.

+0

После публикации моего сообщения я увидел это. Определенно лучший ответ. У вас может быть только DIV, который вы продолжаете заполнять некоторыми материалами AJAX, используя JavaScript. – bdwakefield

+0

Опрос будет быть очень плохим решением для чего-то вроде чата, где паузы могут сильно различаться, и вы хотите, чтобы ответы появлялись быстро y, но в то же время избегайте обременения вашего сервера частыми опросами тысяч клиентов, которые больше ничего не возвращают. Использование протокола HTTP для чего-то не предназначалось для работы и является лучшим решением в этом случае. –

1

Я бы просто эхо/напечатал HTML, когда пошел. Есть несколько разных способов, которыми вы можете иметь приостановку сценария перед отправкой следующего бита. Вам не нужно ничего делать с заголовками или любым специальным кодом, чтобы сообщить браузеру подождать. Пока ваш скрипт все еще работает, он будет отображать HTML-код, полученный из скрипта.

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

Я предлагаю вам исследовать реализацию таких функций с использованием Ajax, а не простого старого HTML. Это позволяет значительно повысить гибкость с точки зрения архитектурного проектирования и пользовательского интерфейса.

2

Клиент закроет соединение, когда он не получит никаких данных за определенное время. Этот тайм-аут не может зависеть от заголовков HTTP. Он специфичен для клиента и обычно устанавливается на 120 секунд IIRC.

Так что вам нужно только регулярно отправлять небольшие объемы данных, чтобы не допустить таймаута.

1

Постарайся навсегда кадр (как в Gmail)

Все эти техники просто рубит, HTTP не предназначен, чтобы сделать это.

1

в конце сценария, использовать что-то вроде этого (предполагая, что вы были буферизация вывода на положив ob_start() в верхней части страницы

<?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 

} 

?> 

Этот сценарий в основном выводит 1 мегабайт текста на 30kbs (имитируется) независимо от того, насколько быстро происходит соединение с пользователем и сервером.

Смежные вопросы