Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Limitowanie transferu
Forum PHP.pl > Forum > PHP
CyklOP
Witam, ostatnio zostałem postawiony przed problemem ograniczenia transferu przy przesyłaniu pliku przez protokół http (NIE ftp!).

Usiłowałem znaleźć odpowiedź na to pytanie zarówno na forum jak i w internecie, niestety nie znalazłem ani śladu informacji na ten temat.

Ograniczenie takie miałoby zostać narzucone przez php, a nie jakąś konfigurację serwera, albo przez program na nim zainstalowany.

Mój obecny pomysł to użycie funkcji, która po przesłaniu do bufora serwera pakietu czeka z wysłaniem kolejnego 1 sekundę (gdy $delay=1).

  1. <?php
  2.  
  3. function readfile_chunked ($filename,$delay,$kb_per_s) {
  4. $chunksize = $kb_per_s*(1024); // how many kbytes per chunk
  5. $buffer = '';
  6. $handle = fopen($filename, 'rb');
  7. if ($handle === false) {
  8. return false;
  9. }
  10. while (!feof($handle)) {
  11. $buffer = fread($handle, $chunksize);
  12. print $buffer;
  13. sleep($delay);
  14.  
  15. }
  16. return fclose($handle);
  17. }
  18.  
  19. ini_set( 'output_buffering','Off' );
  20. //ini_set( 'implicit_flush','On' );
  21.  
  22. header("Content-type: application/download");
  23. header('Content-Disposition: attachment; filename="'.$name.'"');
  24. readfile_chunked($name,1,10);
  25.  
  26. ?>


Takie rozwiązanie na pewno działa, bo testowałem - być może ktoś jednak ma uwagi co do wydajności takiego rozwiązania (czy obsługiwanie downloadu w ten sposób na stronie z dużą ilością odwiedzin nie wykończy serwera), a także ewentualnie wysłucham pomysłów i uwag.

Obecne rozwiązanie (chyba?) nie opóźnia wysyłki przy słabych łączach, gdy transfer i tak jest mniejszy niż ograniczenie.

Jeśli rozwiązanie jest ok, to mam nadzieję, że komuś kto kiedyś będzie go szukał też się przyda.
andrzejb
jezeli to bedzie sie sypac to skieruj download na inny port serwera httpd i tam ograniczaj predkosc ustawieniami serwera lub firewallem
Spirit86
odradzam tej metody, serwer padnie.
Jak będzie miał do obsługi załóżmy 200 klientów, a każdy ściąga plik po 10MB, serwer zostanie koszmarnie obciążony. Osobiście polecałbym takie rozwiązanie:

do małych plików, możesz bez problemu streamować
natomiast większe po prostu przekieruj się headerem.
CyklOP
Cytat
do małych plików, możesz bez problemu streamować
natomiast większe po prostu przekieruj się headerem.


A czy przypadkiem nie jest tak, że jedyna różnica między dużymi plikami a małymi to czas działania skryptu? No bo do pamięci ładowane jest tylko:
$chunksize = $kb_per_s*(1024);
czyli przykładowo 10 kilobajtów...
Chyba, że sam fakt działania w tle kilkuset "procesów" (przy kilkuset downloadach naraz) niezależnie od tego co te procesy robią jest dużym obciążeniem... ale czy wtedy nie jest tak, że nie ma znaczenia czy to duże czy małe pliki, a jedynie ile średnio w trakcie sekundy uzytkownikow sciaga pliki (jakiekolwiek?)?
Spirit86
z tego co wiem, to inpreter php działa cały czas, bo musi on otworzyć linijka po linijce plik. Czyli zabiera się za coś co do niego nie należy, bo od wysyłania plików jest apache np.

możesz to zmierzyć poprzez np. ściąganie pliku bezpośrednio z serwera,no i ze skryptu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.