簡體   English   中英

PHP / Javascript:我如何限制下載速度?

[英]PHP/Javascript: How I can limit the download speed?

我有以下場景:您可以從我們的服務器下載一些文件。 如果您是“普通”用戶,則您的帶寬有限,例如500kbits。 如果您是高級用戶,則沒有帶寬限制,可以盡快下載。 但我怎么能意識到這一點? 這是如何上傳和合作的?

注意:您可以使用PHP執行此操作,但我建議您讓服務器本身處理限制 如果您想單獨使用PHP來降低下載速度,那么這個答案的第一部分將討論您的選擇,但是您可以在下面找到幾個鏈接,您可以在其中找到如何使用服務器管理下載限制。

有一個PECL擴展,使得這是一個相當簡單的任務,稱為pecl_http ,它包含函數http_throttle 文檔包含一個如何執行此操作的簡單示例。 這個擴展還包含一個HttpResponse ,它沒有很好地記錄ATM,但我懷疑它的setThrottleDelaysetBufferSize方法應該產生所需的結果(節流延遲=> 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_throttlepecl_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM