[英]PHP/Javascript: How I can limit the download speed?
我有以下場景:您可以從我們的服務器下載一些文件。 如果您是“普通”用戶,則您的帶寬有限,例如500kbits。 如果您是高級用戶,則沒有帶寬限制,可以盡快下載。 但我怎么能意識到這一點? 這是如何上傳和合作的?
注意:您可以使用PHP執行此操作,但我建議您讓服務器本身處理限制 。 如果您想單獨使用PHP來降低下載速度,那么這個答案的第一部分將討論您的選擇,但是您可以在下面找到幾個鏈接,您可以在其中找到如何使用服務器管理下載限制。
有一個PECL擴展,使得這是一個相當簡單的任務,稱為pecl_http ,它包含函數http_throttle
。 文檔包含一個如何執行此操作的簡單示例。 這個擴展還包含一個HttpResponse
類 ,它沒有很好地記錄ATM,但我懷疑它的setThrottleDelay
和setBufferSize
方法應該產生所需的結果(節流延遲=> 0.001,緩沖區大小20 ==〜20Kb /秒)。 從事物的外觀來看,這應該是有效的:
$download = new HttpResponse();
$download->setFile('yourFile.ext');
$download->setBufferSize(20);
$download->setThrottleDelay(.001);
//set headers using either the corresponding methods:
$download->setContentType('application/octet-stream');
//or the setHeader method
$download->setHeader('Content-Length', filesize('yourFile.ext'));
$download->send();
如果你不能/不想安裝它,你可以編寫一個簡單的循環:
$file = array(
'fname' => 'yourFile.ext',
'size' => filesize('yourFile.ext')
);
header('Content-Type: application/octet-stream');
header('Content-Description: file transfer');
header(
sprintf(
'Content-Disposition: attachment; filename="%s"',
$file['fname']
)
);
header('Content-Length: '. $file['size']);
$open = fopen($file['fname'], "rb");
//handle error if (!$fh)
while($chunk = fread($fh, 2048))//read 2Kb
{
echo $chunk;
usleep(100);//wait 1/10th of a second
}
當然,如果你這樣做,不要緩沖輸出:),最好添加一個set_time_limit(0);
聲明也是。 如果文件很大,很可能你的腳本會在下載過程中被殺死,因為它會達到最大執行時間。
另一種(可能更可取的)方法是通過服務器配置限制下載速度:
我自己從來沒有限制下載率,但是看看這些鏈接,我認為nginx到目前為止是最簡單的,這是公平的:
location ^~ /downloadable/ {
limit_rate_after 0m;
limit_rate 20k;
}
這使得速率限制立即啟動,並將其設置為20k。 詳細信息可以在nginx維基上找到。
至於阿帕奇而言,這並不是說要困難得多,但它會要求你啟用ratelimit模塊
LoadModule ratelimit_module modules/mod_ratelimit.so
然后,告訴apache應該限制哪些文件是一件簡單的事情:
<IfModule mod_ratelimit.c>
<Location /downloadable>
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 20
</Location>
</IfModule>
您可以使用http_throttle
從pecl_http
PHP擴展:
<?php
// ~ 20 kbyte/s
# http_throttle(1, 20000);
# http_throttle(0.5, 10000);
if (!$premium_user) {
http_throttle(0.1, 2000);
}
http_send_file('document.pdf');
?>
(以上是基於http://php.net/manual/en/function.http-throttle.php的示例。)
如果您的服務器API不允許http_throttle
為您的高級和非高級用戶創建兩個不同的,不可取的URL,請參閱您的HTTP服務器文檔以了解如何限制其中一個。 有關Nginx的示例,請參閱https://serverfault.com/questions/179646/nginx-throttle-requests-to-prevent-abuse 。 后者的好處是可以避免由於PHP殺死腳本而導致下載被提前終止等問題。
有這個PHP用戶土地庫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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.