views:

412

answers:

8

Do I need to pass back any HTTP headers to tell the browser that my server won't be immediately closing the connection and to display as the HTML is received? Is there anything necessary to get the HTML to incrementally display like flush()?

This technique used to be used for things like chat, but I'm thinking about using it for a COMET type application.

A: 

Depending on what you are doing, you could just echo as your script proceeds, this will then send the html to the browser as it is echoed.

Toby Allen
+1  A: 

I think a more robust solution is a page with a Javascript timer that polls the server for new data. Keeping the response open is not something the HTTP protocol was designed for.

cdonner
After posting mine I saw this. Definitely the better answer. You can just have a DIV that you keep filling with some AJAX stuff using the JavaScript.
bdwakefield
Polling would be a very bad solution for something like a chat, where pauses can vary a lot, and you want responses to appear quickly but at the same time avoid burdening your server with frequent polls by thousands of clients that don't return anything most of the time. Using the HTTP protocol for something it was not designed for works and is the better solution in such a case.
Michael Borgwardt
+1  A: 

I would just echo / print the HTML as I went. There are a few different ways you can have the script pause before sending the next bit. You shouldn't need to do anything with headers or any special code to tell the browser to wait. As long as your script is still running it will render the HTML it receives from the script.

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

I would suggest you investigate implementing such functionality using Ajax, rather than plain old HTML. This allows you much more flexibility in terms of architectural design and user interface

Conrad
+2  A: 

The client will close the connection when it does not receive any data for a certain time. This timeout cannot be influenced by HTTP headers. It is client-specific and usually set to 120 seconds IIRC.

So all you have to do is send small amounts of data regularly to avoid hitting the timeout.

Michael Borgwardt
+1  A: 

Try forever frame (like in gmail)

All of these technics are just hacks, http isn't designed to do this.

erenon
+10  A: 

Long polling is a common technique to do something like this; to briefly summarise, it works as follows:

  1. The client sends an XHR to the server.

    • If there is data ready, the server returns this immediately.
    • If not, the server keeps the connection open until data does become available, then it returns this.
    • If the request times-out, go back to 1).
  2. The page running on the client receives this data, and does what it does with it.

  3. Go back to 1)

This is how Facebook implements its chat feature.

This article also clears up some of the misconceptions of long-polling, and details some of the benefits of doing so.

Perspx
This is what I was looking for, despite the fact the title of the question is mangled.
altCognito
It certainly works with Facebook - notifications, chat and many other features work using this method.
Perspx
Keep in my that Facebook uses Erlang on the backend to handle chat so it can manage all the open connections. Apache/PHP would never be able to scale that high.
Brent Baisley
+1  A: 

at the end of your script, use something like this (assuming you had output buffering on by putting ob_start() at the top of your page

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

}

?>

That script basically outputs 1 megabyte of text at 30kbs (simulated) no matter how fast the user and server connection is.

Ozzy