Come limitare la velocità di risposta in uscita dallo script php?
Domanda
Come limitare la velocità di risposta in uscita dallo script php? Così ho un dato di generazione di script in relazione keep-alive. E 'appena si apre il file e lo legge. Come limitare la velocità in uscita ??p>
(ormai ho tale codice)
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)));
}
}
}
Che cosa devo fare per limite di velocità di risposta (limite di per esempio 50 kb / s)
Soluzione
Modificare il file di output per scaglionato piuttosto che emettere l'intero file in una sola volta.
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, 51200)); # 51200 bytes = 50 kB
sleep(1);
}
Questa uscita 50kB volontà quindi attendere un secondo, finché l'intero file viene emesso. Dovrebbe tappare la larghezza di banda a circa 50kB / secondo.
Anche se questo è possibile all'interno di PHP, mi piacerebbe utilizzare il web-server per controllare il throttling .
Altri suggerimenti
Non vorrei usare php per limitare la larghezza di banda:
Per Apache: Bandwidth Mod v0.7 ( How-To -? larghezza di banda limitatore Per Apache2 )
Per Nginx: http://wiki.nginx.org/NginxHttpCoreModule#limit_rate
Per Lighttpd: http: //redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping Questo permette anche di configurare la velocità di ogni connessione in PHP
Si può leggere n byte e quindi utilizzare l'uso del sonno (1) di aspettare un secondo, come suggerito qui .
Credo che il metodo di 'Ben S' e 'igorw' è sbagliato perché esse implicano larghezza di banda illimitata, che è un falso presupposto. Fondamentalmente uno script che dice
while(!feof($fh)) {
print(fread($fh, $chunk_size));
sleep(1);
}
sarà una pausa per un secondo dopo l'emissione $ il numero di byte chunk_size indipendentemente da quanto tempo c'è voluto. Se, per esempio se il vostro rendimento corrente è 100kb e si desidera per lo streaming a 250KB, lo script precedente prende 2,5 secondi per fare il print () e poi aspettare ancora un altro secondo, spingendo in modo efficace la vera larghezza di banda fino a circa 70kb.
La soluzione dovrebbe o misurare il tempo impiegato per PHP per completare la statemnt print () o utilizzare un buffer e chiamata a filo con ogni fread (). Il primo approccio potrebbe essere:
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);
}
, mentre il secondo sarebbe qualcosa di simile:
ob_start();
while(!feof($fh)) {
print(fread($fh, $chunk_size));
flush();
ob_flush();
sleep(1);
}
Si potrebbe collegare un bandwidth-throttle/bandwidth-throttle
ad un flusso:
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);