Как ограничить скорость исходящего ответа от php-скрипта?

Как ограничить скорость исходящего ответа от php-скрипта? Поэтому у меня есть сценарий, генерирующий данные в режиме keep-alive. Он просто открывает файл и читает его. Как ограничить исходящую скорость

(К тому времени у меня такой код)

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))); } } } 

Итак, что мне делать, чтобы ограничить скорость реакции (ограничение, например, 50 кбит / с)

Измените вывод файла, чтобы он был помещен в шахматном порядке, чтобы выводить весь файл за один раз.

 # output file while(!feof($fh)) { # output file without bandwidth limiting print(fread($fh, 51200)); # 51200 bytes = 50 kB sleep(1); } в # output file while(!feof($fh)) { # output file without bandwidth limiting print(fread($fh, 51200)); # 51200 bytes = 50 kB sleep(1); } 

Это приведет к выходу 50kB, а затем подождите одну секунду, пока не будет выведен весь файл. Он должен ограничивать пропускную способность до 50 кБ / с.

Несмотря на то, что это возможно в PHP, я бы использовал ваш веб-сервер для управления дросселированием .

Я бы не использовал php для ограничения пропускной способности:

Для Apache: Bandwidth Mod v0.7 ( How-To – Ограничитель пропускной способности для Apache2 )

Для Nginx: http://wiki.nginx.org/NginxHttpCoreModule#limit_rate

Для Lighttpd: http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping Это даже позволяет вам настроить скорость для каждого соединения в PHP

Вы можете прочитать n байтов, а затем использовать sleep (1), чтобы подождать секунду, как это предлагается здесь .

Я думаю, что метод «Бен С» и «igorw» неверен, потому что они подразумевают неограниченную пропускную способность, которая является ложным предположением. В основном сценарий, который говорит

 while(!feof($fh)) { print(fread($fh, $chunk_size)); sleep(1); } 

будет приостановлен на секунду после вывода $ chunk_size числа байтов, независимо от того, сколько времени прошло. Если, например, если ваша текущая пропускная способность составляет 100 кбайт, а вы хотите передать ее на скорости 250 кбайт, для выполнения печати () будет выполняться 2,5 секунды для выполнения печати (), а затем ждать еще одну секунду, эффективно нажимая реальную полосу пропускания примерно до 70 кб.

Решение должно либо измерить время, необходимое PHP для завершения print () statemnt, либо использовать буфер и сбросить флажок с каждым fread (). Первый подход:

 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); } 

а второй – что-то вроде:

 ob_start(); while(!feof($fh)) { print(fread($fh, $chunk_size)); flush(); ob_flush(); sleep(1); } 

Вы могли бы подключить bandwidth-throttle/bandwidth-throttle к потоку:

 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);