¿Cómo limitar la velocidad de respuesta de salida del script php?
Pregunta
Cómo limitar la velocidad de respuesta de salida del script php? Así que tengo un conjunto de datos de generación de secuencia de comandos en conexión keep-alive. Simplemente abre el archivo y lo lee. ¿Cómo limitar la velocidad de salida
(Por ahora tengo tal código)
if(isset($_GET[FILE]))
{
$fileName = $_GET[FILE];
$file = $fileName;
if (!file_exists($file))
{
print('<b>ERROR:</b> php could not find (' . $fileName . ') please check your settings.');
exit();
}
if(file_exists($file))
{
# stay clean
@ob_end_clean();
@set_time_limit(0);
# keep binary data safe
set_magic_quotes_runtime(0);
$fh = fopen($file, 'rb') or die ('<b>ERROR:</b> php could not open (' . $fileName . ')');
# content headers
header("Content-Type: video/x-flv");
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, filesize($file)));
}
}
}
Entonces, ¿qué debo hacer para alcanzar el límite de velocidad de la respuesta (por ejemplo, límite a 50 kb / s)
Solución
Cambiar su salida del archivo a ser escalonada en lugar de que la salida de todo el archivo de una sola vez.
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, 51200)); # 51200 bytes = 50 kB
sleep(1);
}
Esta es la salida 50kB luego esperar un segundo hasta que todo el archivo se emite. Se debe tapar el ancho de banda a alrededor de 50 KB / s.
A pesar de que esto es posible dentro de PHP, me utilizar su servidor web para controlar el estrangulamiento .
Otros consejos
Yo no usaría php para limitar el ancho de banda:
Para Apache: de ancho de banda Mod v0.7 ( Cómo se hace? - Anchura de banda limitador Para Apache 2)
Para Nginx: http://wiki.nginx.org/NginxHttpCoreModule#limit_rate
Para Lighttpd: http: //redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping Esto incluso le permite configurar la velocidad por conexión en PHP
Usted puede leer n bytes y luego usar el uso del sueño (1) que esperar un segundo, como se sugiere aquí .
Creo que el método de 'Ben S' y 'igorw' está equivocada porque implican ancho de banda ilimitado, que es una suposición falsa. Básicamente, un guión que dice
while(!feof($fh)) {
print(fread($fh, $chunk_size));
sleep(1);
}
hará una pausa por un segundo después de la salida de $ chunk_size número de bytes sin importar el tiempo que tomó. Si, por ejemplo, si su rendimiento actual es de 100 kb y que desea transmitir a 250 kb, la secuencia de comandos se llevará a 2,5 segundos para hacer la impresión () y luego esperar otro segundo, empujando efectivamente el ancho de banda real de hasta 70kb alrededor.
La solución tampoco debe medir el tiempo que tomó para PHP para completar la statemnt de impresión () o usar un tampón y llamada a ras de cada fread (). El primer enfoque sería:
list($usec, $sec) = explode(' ', microtime());
$time_start = ((float)$usec + (float)$sec);
# output packet
print(fread($fh, $packet_size));
# get end time
list($usec, $sec) = explode(' ', microtime());
$time_stop = ((float)$usec + (float)$sec);
# wait if output is slower than $packet_interval
$time_difference = $time_stop - $time_start;
if($time_difference < (float)$packet_interval) {
usleep((float)$packet_interval*1000000-(float)$time_difference*1000000);
}
mientras que el segundo sería algo como:
ob_start();
while(!feof($fh)) {
print(fread($fh, $chunk_size));
flush();
ob_flush();
sleep(1);
}
bandwidth-throttle/bandwidth-throttle
a una corriente:
use bandwidthThrottle\BandwidthThrottle;
$in = fopen(__DIR__ . "/resources/video.mpg", "r");
$out = fopen("php://output", "w");
$throttle = new BandwidthThrottle();
$throttle->setRate(500, BandwidthThrottle::KIBIBYTES); // Set limit to 500KiB/s
$throttle->throttle($out);
stream_copy_to_stream($in, $out);