Как ограничить скорость исходящего ответа из сценария PHP?

StackOverflow https://stackoverflow.com/questions/3110725

Вопрос

Как ограничить скорость исходящего ответа из сценария PHP? Таким образом, у меня есть скрипт, генерирующие данные в подключении. Он просто открывает файл и читает его. Как ограничить исходящую скорость

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

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

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

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

Другие советы

Я бы не использовал PHP, чтобы ограничить пропускную способность:

Для Apache: Пропускная способность мод v0.7 (Как рекомендовать - ограничитель полосы пропускания для Apache2)

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

Для LightTPD: http://redmine.lighttpd.net/projects/lighttpd/wiki/docs:traffic-shaping Это даже позволяет настроить скорость на соединение в php

Вы можете читать N Bytes, а затем использовать использование Sleep (1), чтобы подождать секунду, как следует здесь.

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

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

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

Решение должно либо измерить время, необходимое для PHP, чтобы завершить STATEMNT Print (), либо использовать буфер, и вызовать промывку с помощью каждого 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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top