如何限制php脚本的传出响应速度?

发布于 2024-09-06 17:32:22 字数 841 浏览 3 评论 0原文

如何限制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)

How to limit speed of outgoing response from php script? So I have a script generating data in keep-alive connection. It just opens file and reads it. How to limit outgoing speed

(By now i have such 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))); 
   } 
  } 
 }

So what shall I do to limit speed of response (limit to for example 50 kb/s)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

记忆で 2024-09-13 17:32:22

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

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

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

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

Change your file output to be staggered rather that outputting the whole file in one go.

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

This will output 50kB then wait one second until the whole file is output. It should cap the bandwidth to around 50kB/second.

Even though this is possible within PHP, I'd use your web-server to control the throttling.

可爱咩 2024-09-13 17:32:22

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

对于 Apache:Bandwidth Mod v0.7 (操作方法 - Apache2 的带宽限制器)

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

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

I wouldn't use php to limit the bandwidth:

For Apache: Bandwidth Mod v0.7 (How-To - Bandwidth Limiter For Apache2)

For Nginx: http://wiki.nginx.org/NginxHttpCoreModule#limit_rate

For Lighttpd: http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping This even allows you to configure the speed per connection in PHP

瀞厅☆埖开 2024-09-13 17:32:22

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

You can read n bytes and then use use sleep(1) to wait a second, as suggested here.

断舍离 2024-09-13 17:32:22

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

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

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

解决方案应该测量 PHP 完成 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);
    }

I think the method of 'Ben S' and 'igorw' is wrong because they imply unlimited bandwidth which is a false assumption. Basically a script that says

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

will pause for a second after outputting $chunk_size number of bytes regardless of how long it took. If for example if your current throughput is 100kb and you want to stream at 250kb, the script above will take 2.5 seconds to do the print() and then wait yet another second, effectively pushing the real bandwidth down to around 70kb.

The solution should either measure the time it took for PHP to complete the print() statemnt or use a buffer and call flush with every fread(). The first approach would be:

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

while the second would be something like:

ob_start();
while(!feof($fh)) {
       print(fread($fh, $chunk_size));
       flush();
       ob_flush();
       sleep(1);
    }
错々过的事 2024-09-13 17:32:22

您可以将 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);

You could attach a bandwidth-throttle/bandwidth-throttle to a stream:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文