PHPスクリプトからの発信応答の速度を制限する方法は?
質問
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の制限)
解決
ファイル全体を一度に出力するのではなく、ファイルの出力をずらして変更します。
# output file
while(!feof($fh))
{
# output file without bandwidth limiting
print(fread($fh, 51200)); # 51200 bytes = 50 kB
sleep(1);
}
これにより、50kbが出力され、ファイル全体が出力されるまで1秒待ちます。帯域幅を約50kb/秒にキャップする必要があります。
これはPHP内で可能ですが、私はそうです Webサーバーを使用して、スロットリングを制御します.
他のヒント
帯域幅を制限するためにPHPを使用しません。
Apacheの場合: 帯域幅mod v0.7 (ハウツー - apache2の帯域幅リミッター)
nginxの場合: http://wiki.nginx.org/nginxhttpcoremodule#limit_rate
lighttpdの場合: http://redmine.lighttpd.net/projects/lighttpd/wiki/docs:trafficshaping これにより、PHPで接続ごとの速度を構成することもできます
nバイトを読んでから、スリープ(1)を使用して1秒待つことができます。 ここ.
「ベンS」と「イゴル」の方法は間違っていると思います。なぜなら、彼らは誤った仮定である無制限の帯域幅を暗示しているからです。基本的に書かれたスクリプト
while(!feof($fh)) {
print(fread($fh, $chunk_size));
sleep(1);
}
$ chunk_size数のバイト数を出力してから1秒間一時停止します。たとえば、現在のスループットが100kbで、250kbでストリーミングする場合、上記のスクリプトは2.5秒かかり、印刷()を実行し、さらに秒待ち、実際の帯域幅を約70kbに押し下げます。
ソリューションは、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);
}
2番目は次のようなものです。
ob_start();
while(!feof($fh)) {
print(fread($fh, $chunk_size));
flush();
ob_flush();
sleep(1);
}
あなたは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);