如何限制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 kb / s)
答案 0 :(得分:4)
将文件输出更改为交错,而不是一次性输出整个文件。
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, 51200)); # 51200 bytes = 50 kB
sleep(1);
}
这将输出50kB然后等待一秒,直到输出整个文件。它应该将带宽限制在大约50kB /秒。
尽管这在PHP中是可行的,但我使用您的网络服务器来控制限制。
答案 1 :(得分:2)
我不会用php来限制带宽:
对于Apache:Bandwidth Mod v0.7(How-To - Bandwidth Limiter For Apache2)
对于Nginx:http://wiki.nginx.org/NginxHttpCoreModule#limit_rate
对于Lighttpd:http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:TrafficShaping这甚至允许您在PHP中配置每个连接的速度
答案 2 :(得分:0)
您可以读取n个字节,然后按照建议here使用use sleep(1)等待一秒钟。
答案 3 :(得分:0)
我认为'Ben S'和'igorw'的方法是错误的,因为它们意味着无限的带宽,这是一个错误的假设。基本上是一个说
的脚本while(!feof($fh)) {
print(fread($fh, $chunk_size));
sleep(1);
}
输出$ chunk_size字节数后,将暂停一秒,无论花费多长时间。例如,如果您当前的吞吐量为100kb并且您希望以250kb进行流式传输,则上述脚本将花费2.5秒来执行print(),然后等待另一秒,从而有效地将实际带宽降低到大约70kb。
解决方案应该测量PHP完成print()statemnt所花费的时间,或者使用缓冲区并使用每个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);
}
答案 4 :(得分:0)
您可以将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);