DowlLoad ограничение скорости клиента.

MagicGTS

Новичок
DowlLoad ограничение скорости клиента.

Видел в форуме много вопросов на эту тему, но вот ответов так и не нашёл. Сам немного поковырялся и сделал сам. Основа 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");
	}
?>
Решение работает в Win* системах, а значит и *nix тоже.
Реализовано малость кривовато, но зато работает. Счас думаю как-бы всё по красивей написать, или применить другой подход.
Данный код позволяет контролировать скорость с шагом в 64 кило, если изменить отдаваемую за раз порцию ($chain_size), то можно получить более точный\грубый контроль.
Если есть предложения\коментарии пишите :)

-~{}~ 16.06.04 14:29:

На своей машине (типа локально, мой сервер и клиент в одном лице) очень стабильно держит скорость при $speed_hold=6 (384 kbps), с повышением скорости несправляется винт, и появляется явление "биения" скорости. Она прыгает около установленной отметки с завидной непереодичностью (у меня начинает уже с $speed_hold=8 (512 kbps) ) причем в очень широких пределах (от 64 до 3000).
 

MagicGTS

Новичок
А прокоментировать вот эти моменты: set_time_limit(300); ? Там чето не совсем понятно...
 

desperado

Новичок
м... по ссылке полнустью функция, а вкратце:
скрипт работает не вечно, а как ему сказано в конфиге (30 секунд) вот мы ему жизнь и продлеваем на 300 секунд каждые 240 секунд.
 

MagicGTS

Новичок
По ссылке я глянул функцию, тока вот не совсем мне все моменты понятны,а вот зачем продлять время жизни каждые n секунд? Не проще (или лучше) сделать ему жизнь сразу и на долго? (меня глючит или как? где-то я это уже писал\читал?)

-~{}~ 16.06.04 18:48:

Ладно, зачем продлять жизнь, а не дарить бесмертие я понял. Появился другой вопрос, почему этот скрипт постоянно жрёт память? Причем жрёт её в немеренных количествах?
 
Сверху