Re: Re: stream_set_timeout() stream_get_meta_data() etc...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Many thanks to Richard and Skippy.

Skippy: Your suggestion to set non-blocking mode (stream_set_blocking) was the magic key to success.

Here is the code I ended up with, I left some test stuff included so anyone who may need it has a good start.

$fp= fopen($file, 'rb' );
	if (!$fp) {die ("Failed to open $file, errors: $errstr ($errno)<br>\n");
	}//end if
>
  	stream_set_blocking($fp, FALSE );	
	$html= ''; $chunk= '';
	$start= time();
	while (!feof($fp)){
		sleep($interval);
		$chunk= fread($fp, 10000); 		//chunks, packets are limited anyhow
		$length= strlen($chunk);
		if($length)== 0){echo "<div style=\"color:blue\">Read zero bytes</div>";}
		$html .= $chunk;
		echo "<div>At " . date("h:s") . ">>  $length bytes read</div>"; 		
		ob_flush();	
		if (time() - $start > $timelimit){echo("<div>style= \"color:red\">Timeout!</div>\n"); break;}		
	}//end while

Putting the sleep() first thing helps everything get started better. Seems as if fread() needs a little time after fopen().


ob_flush() is neat. It forces the client browser to render progress. I've always been told you can't make a progress bar or list with php. Well here it is, at least it works with IE6 and Mozilla.


Skippy wrote:
Quoting Al <news@xxxxxxxxxxxxx>:

Darn, I left out an important function, the fread(). Code snip should be:
 $fp= fopen("http://www.anything.com/foo.html, 'rb');
 if(!fp) {do something different}
 stream_set_timeout($fp, 2);
 $contents= fread($fp, 200000);
 $status= stream_get_meta_data($fp);
 if($status[timed_out] {do something};

It appears to me there is a basic logic problem.  The script must get
past the fread() function before it gets to the stream_get_meta_data($fp).
But, it hangs up on fread() and the script times out.


Set the stream to non-blocking mode (stream_set_blocking). Now all
read functions will return instantly, regardless if any data came
through. You can test whether you got back anything by checking the
returned data. If you now read from the non-blocked stream in a cycle,
you will have no "dead" times and you will always retain control.
Only now can you rely on comparing time() with a control value set
before entering the cycle and decide to abort if a number of seconds
has passed.

stream_set_timeout() will be pretty much superfluous at this point
and may even hinder your reading from the stream.

Important tip: in a non-blocking cycle you MUST have an usleep()
somewhere. Otherwise that cycle will consume 100% CPU while it
runs. An usleep(1000) will suffice, adjust as needed.


-- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux