Wie Geschwindigkeit ausgehenden Antwort von PHP-Skript zu begrenzen?
Frage
Wie Geschwindigkeit ausgehenden Antwort von PHP-Skript zu begrenzen? Also habe ich ein Skript Erzeugungsdaten in Keep-Alive-Verbindung. Es öffnet sich nur Datei und liest sie. Wie zu begrenzen abgehende Geschwindigkeit
(Inzwischen habe ich einen solchen Code)
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)));
}
}
}
Also, was soll ich tun Grenze der Geschwindigkeit der Reaktion (Grenze zu beispielsweise 50 kb / s)
Lösung
Ändern Sie Ihre Dateiausgabe eher gestaffelt werden, dass die gesamte Datei auf einmal ausgegeben werden.
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, 51200)); # 51200 bytes = 50 kB
sleep(1);
}
Dies wird Ausgang 50kB dann 1 Sekunde warten, bis die gesamte Datei ausgegeben wird. Es sollte die Bandbreite um 50 kB / s Kappe.
Auch wenn dies möglich ist, innerhalb von PHP, würde ich Verwenden Sie Ihren Web-Server die Drosselung steuern.
Andere Tipps
Ich würde nicht PHP verwenden, um die Bandbreite zu begrenzen:
Für Apache: Bandbreite Mod v0.7 ( How-To - Bandbreite Limiter Für Apache2 )
Für Nginx: http://wiki.nginx.org/NginxHttpCoreModule#limit_rate
Für Lighttpd: http: Diese //redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping selbst können Sie die Geschwindigkeit pro Verbindung in PHP
konfigurierenSie können die n Bytes gelesen und dann Verwendung sleep (1) verwenden, um eine Sekunde zu warten, wie vorgeschlagen hier .
Ich denke, die Methode des ‚Ben S‘ und ‚igorw‘ falsch ist, weil sie unbegrenzte Bandbreite bedeuten, die eine falsche Annahme ist. Im Grunde ein Skript, das sagt
while(!feof($fh)) {
print(fread($fh, $chunk_size));
sleep(1);
}
wird für eine zweite Pause nach $ chunk_size Anzahl von Bytes, unabhängig davon ausgibt, wie lange es dauerte. Wenn zum Beispiel, wenn Ihre aktuelle Durchsatz 100kb ist und möchten Sie bei 250kb streamen, über das Skript 2,5 Sekunden dauern, den Druck zu tun () und dann warten noch eine weitere Sekunde, effektiv die reale Bandbreite auf rund 70kb drücken.
Die Lösung sollte entweder die Zeit messen, dauerte es für PHP die print () statemnt oder verwenden Sie einen Puffer und Call bündig mit jedem fread abzuschließen (). Der erste Ansatz wäre:
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);
}
, während das zweite wäre so etwas wie:
ob_start();
while(!feof($fh)) {
print(fread($fh, $chunk_size));
flush();
ob_flush();
sleep(1);
}
könnten Sie hängen einen bandwidth-throttle/bandwidth-throttle
einen Strom:
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);