MagicGTS
Новичок
DowlLoad ограничение скорости клиента.
Видел в форуме много вопросов на эту тему, но вот ответов так и не нашёл. Сам немного поковырялся и сделал сам. Основа DowlLoad скрипта - это плагиат с сылки данной на этом сайте, с значительными изменениями. А часть ответственная за скорость сделана мной.
Решение работает в Win* системах, а значит и *nix тоже.
Реализовано малость кривовато, но зато работает. Счас думаю как-бы всё по красивей написать, или применить другой подход.
Данный код позволяет контролировать скорость с шагом в 64 кило, если изменить отдаваемую за раз порцию ($chain_size), то можно получить более точный\грубый контроль.
Если есть предложения\коментарии пишите
-~{}~ 16.06.04 14:29:
На своей машине (типа локально, мой сервер и клиент в одном лице) очень стабильно держит скорость при $speed_hold=6 (384 kbps), с повышением скорости несправляется винт, и появляется явление "биения" скорости. Она прыгает около установленной отметки с завидной непереодичностью (у меня начинает уже с $speed_hold=8 (512 kbps) ) причем в очень широких пределах (от 64 до 3000).
Видел в форуме много вопросов на эту тему, но вот ответов так и не нашёл. Сам немного поковырялся и сделал сам. Основа DowlLoad скрипта - это плагиат с сылки данной на этом сайте, с значительными изменениями. А часть ответственная за скорость сделана мной.
PHP:
<?php
set_time_limit (0);
$chain_size=1024*64;
$workDir = "./";
$allowedHost = "localhost";
if (isset($_GET["file"]) && $_GET["file"]!="" && file_exists($workDir.$_GET["file"]) )
{
$workFileName = $_GET["file"];
$fd = fopen ($workDir.$workFileName, "rb");
$workFileSize = filesize ($workDir.$workFileName);
$contentSize = $workFileSize;
if (isset($_SERVER["HTTP_RANGE"]))
{
preg_match ("/bytes=(\d+)-/", $_SERVER["HTTP_RANGE"], $m);
$contentSize = $workFileSize - intval($m[1]);
$p1 = $workFileSize-$contentSize;
$p2 = $workFileSize-1;
$p3 = $workFileSize;
fseek ($fd, $p1);
header ("HTTP/1.1 206 Partial Content");
}
header ("Date: " . getGMTDateTime ());
$full_part=(int)($contentSize/$chain_size);
$patch_part=$contentSize-$full_part*$chain_size;
header ("Cache-Control: None");
header ("Pragma: no-cache");
header ("Accept-Ranges: bytes");
header ("Content-Disposition: inline; filename=\"" . $workFileName . "\"");
if (isset($_SERVER["HTTP_RANGE"]))
{
header ("Content-Range: bytes " . $p1 . "-" . $p2 . "/" . $p3);
}
header ("Content-Length: " . $contentSize);
header ("Content-Type: application/octet-stream");
header ("Proxy-Connection: close");
$full_part=(int)($contentSize/$chain_size);
$patch_part=$contentSize-$full_part*$chain_size;
/*Кусочек относящийся к скорости:*/
$s_time=time();
$send=$full_part;
$speed_hold=100;
$w_t=$speed_hold;
$s_t=$w_t;
/*опять "обычный" скрипт:*/
while($full_part>=0)
{
/*Скорость*/
$f_time=time()-$s_time;
if($f_time>=2)
{
$s_time=time();
if($send-$full_part>=$speed_hold*$f_time)
{
$w_t=$speed_hold;
}
else
{
$w_t=0;
}
$send=$full_part;
}
if($s_t<=0 && $w_t!=0)
{
$s_t=$w_t;
sleep(1);
continue;
}
$s_t--;
/*И завершение скрипта*/
$contents = fread ($fd, $chain_size);
echo $contents;
$full_part--;
}
$contents = fread ($fd, $patch_part);
echo $contents;
fclose ($fd);
}
else
{
header ("HTTP/1.1 404 Object Not Found ");
}
function getGMTDateTime ()
{
$offset = date("O");
$roffset = "";
if ($offset[0] == "+")
{
$roffset = "-";
}
else
{
$roffset = "+";
}
$roffset .= $offset[1].$offset[2];
return (date ("D, j M Y H:i:s", strtotime ($roffset . " hours ")) . " GMT");
}
?>
Реализовано малость кривовато, но зато работает. Счас думаю как-бы всё по красивей написать, или применить другой подход.
Данный код позволяет контролировать скорость с шагом в 64 кило, если изменить отдаваемую за раз порцию ($chain_size), то можно получить более точный\грубый контроль.
Если есть предложения\коментарии пишите
-~{}~ 16.06.04 14:29:
На своей машине (типа локально, мой сервер и клиент в одном лице) очень стабильно держит скорость при $speed_hold=6 (384 kbps), с повышением скорости несправляется винт, и появляется явление "биения" скорости. Она прыгает около установленной отметки с завидной непереодичностью (у меня начинает уже с $speed_hold=8 (512 kbps) ) причем в очень широких пределах (от 64 до 3000).