2

如何限制来自 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 kb/s)

4

5 回答 5

4

将文件输出更改为交错,而不是一次性输出整个文件。

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

这将输出 50kB,然后等待一秒钟,直到输出整个文件。它应该将带宽限制在 50kB/秒左右。

尽管这在 PHP 中是可能的,但我会使用您的网络服务器来控制节流

于 2010-06-24T14:17:30.523 回答
2

我不会使用 php 来限制带宽:

对于 Apache:Bandwidth Mod v0.7How-To - Bandwidth Limiter For Apache2

对于 Nginx:http ://wiki.nginx.org/NginxHttpCoreModule#limit_rate

对于 Lighttpd:http: //redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping这甚至允许您在 PHP 中配置每个连接的速度

于 2010-06-24T14:25:07.667 回答
0

您可以读取 n 个字节,然后使用 use sleep(1) 等待一秒钟,如此处所建议

于 2010-06-24T14:18:03.873 回答
0

我认为“Ben S”和“igorw”的方法是错误的,因为它们暗示无限带宽,这是一个错误的假设。基本上是一个脚本说

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

在输出 $chunk_size 个字节后,无论花费多长时间,都会暂停一秒钟。例如,如果您当前的吞吐量是 100kb,而您希望以 250kb 的速度进行流式传输,那么上面的脚本将花费 2.5 秒来执行 print(),然后再等待一秒,从而有效地将实际带宽降低到 70kb 左右。

解决方案应该测量 PHP 完成 print() 语句所花费的时间,或者使用缓冲区并在每次 fread() 时调用 flush。第一种方法是:

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);
    }
于 2011-10-18T17:17:20.003 回答
0

您可以将 a 附加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);
于 2015-08-09T09:14:10.363 回答