glam
Новичок
докачка и производительность - помогите разобраться
Всем привет!
В свое время слямзил в интернете код, который отдает файлы с поддержкой докачки.
Отмечу, что насколько я понял, качаются файлы нормально, в несколько потоков и докачка поддерживается - проверял, скачивая программой Free Download Manager.
В последнее время с ростом количества посетителей беспокоит производительность - сайт стал заметно тормозить.
Решил внести "тюнинг" в код и добавить паузу, чтобы понизить скорость скачки. И код привел меня в некоторое недоумение.
Сейчас пытаюсь разобраться в коде и столкнулся с некоторыми проблемами. Сначала приведу код, который я использую и дополню его своими комментариями с вопросами:
-~{}~ 18.10.07 14:29:
И еще вопрос.
Насколько я понимаю, в коде нет цикла частичной отдачи файла и цикл есть коде самого браузера, браузер циклично обращается к скрипту, а мой код итерационно получает запрос с определенным смещением и тдает запрашиваемые куски. Это моя догадка (домысел) - я правильно понимаю?
-~{}~ 18.10.07 14:45:
Насколько я понимаю, нужно убрать строчку
И добавить после посылки всех заголовков, вместо строки
строчки:
Ничего не поломается с докачкой?
Я честно говоря не понимаю, как работают ranges в указанном коде. Ведь приведенный код получает команду ОТКУДА читать, но не получает команду - СКОЛЬКО читать. И если браузер запускает несколько потоков скачки, то как приведенный код отдаст в потоке браузера столько сколько нужно? Ведь код читает все до конца файла в любом потоке? И вообще говоря получается, что получаются зоны дублирования? Или браузер сам принудительно обрывает поток и обращение к скрипту, когда получил сколько нужно в текущем потоке?
Всем привет!
В свое время слямзил в интернете код, который отдает файлы с поддержкой докачки.
Отмечу, что насколько я понял, качаются файлы нормально, в несколько потоков и докачка поддерживается - проверял, скачивая программой Free Download Manager.
В последнее время с ростом количества посетителей беспокоит производительность - сайт стал заметно тормозить.
Решил внести "тюнинг" в код и добавить паузу, чтобы понизить скорость скачки. И код привел меня в некоторое недоумение.
Сейчас пытаюсь разобраться в коде и столкнулся с некоторыми проблемами. Сначала приведу код, который я использую и дополню его своими комментариями с вопросами:
PHP:
// здесь все понятно, проверяем, существует ли файл, если нет - то посылаем в браузер ошибку
// что файл не найден
if (!file_exists($filename))
{
header ("HTTP/1.0 404 Not Found");
exit;
}
// здесь понятно, определяем размер, дату файла и получаем указатель, если не получилось
// получить указатель - посылаем в браузер ошибку, что запрещен доступ к файлу
$fsize = filesize($filename);
$ftime = date("D, d M Y H:i:s T", filemtime($filename));
$fd = @fopen($filename, "rb");
if (!$fd)
{
header ("HTTP/1.0 403 Forbidden");
exit;
}
// здесь становится интересно, насколько я понял если браузер поддерживает докачку,
// то получаем диапазон и смещаем указатель файла на этот диапазон
if ($HTTP_SERVER_VARS["HTTP_RANGE"])
{
$range = $HTTP_SERVER_VARS["HTTP_RANGE"];
$range = str_replace("bytes=", "", $range);
$range = str_replace("-", "", $range);
if ($range)
{
fseek($fd, $range);
}
}
// а вот тут нипанятнаааа:
// 1) почему читаем все сразу? Халатность в программировании? Или я что-то не понимаю?
// 2) Почему не уменьшили длину чтения на значение смещения? Ошибка в программировании?
// Или я что-то не понимаю?
$content = fread($fd, filesize($filename));
fclose($fd);
// здесь понятно, сообщаем браузеру. отдаем ли кусочками или нет
if ($range) {
header("HTTP/1.1 206 Partial Content");
}
else {
header("HTTP/1.1 200 OK");
}
// здесь понятно, посылаем информацию о файле
header("Content-Disposition: attachment; filename=$fn");
header("Last-Modified: $ftime");
header("Accept-Ranges: bytes");
header("Content-Length: ".($fsize-$range));
// эта строчка непонятна, почему говорим браузеру,
// что диапазон отдачи - ($fsize -1)."/".$fsize)
// я вообще не понимаю, что такое минус один и что за число мы получаем
header("Content-Range: bytes $range-".($fsize -1)."/".$fsize);
header("Content-type: application/octet-stream");
// понятно, отдаем файл (или часть)
print $content;
И еще вопрос.
Насколько я понимаю, в коде нет цикла частичной отдачи файла и цикл есть коде самого браузера, браузер циклично обращается к скрипту, а мой код итерационно получает запрос с определенным смещением и тдает запрашиваемые куски. Это моя догадка (домысел) - я правильно понимаю?
-~{}~ 18.10.07 14:45:
Насколько я понимаю, нужно убрать строчку
PHP:
$content = fread($fd, filesize($filename));
PHP:
print $content;
PHP:
while(!eof($fd))
{
$content = fread($fd, 1024);
print $content;
// чтобы получить скорость 50 килобайт в секунду -
// прочитаем один килобайт и заснем на 1/50 секунды
sleep(1/50);
}
Я честно говоря не понимаю, как работают ranges в указанном коде. Ведь приведенный код получает команду ОТКУДА читать, но не получает команду - СКОЛЬКО читать. И если браузер запускает несколько потоков скачки, то как приведенный код отдаст в потоке браузера столько сколько нужно? Ведь код читает все до конца файла в любом потоке? И вообще говоря получается, что получаются зоны дублирования? Или браузер сам принудительно обрывает поток и обращение к скрипту, когда получил сколько нужно в текущем потоке?