Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Zliczanie zakończonych pobrań
Forum PHP.pl > Forum > Przedszkole
splif
Witam,
na wstępie powiem, że nie jestem programistą, prowadzę stronę internetową i chciałbym zaczerpnąć informacji od ekspertów smile.gif.

Mam serwis z którego można pobrać programy, i chciałbym zliczać dla każdego z tych programów: ilość rozpoczętych pobrań (Wszyscy Użytkownicy) ilość rozpoczętych pobrań (Unikalni Użytkownicy) oraz ilość zakończonych pobrań (również unikalne). O ile z dwoma pierwszymi nie mam problemu, nie wiem jak zmierzyć zakończone pobrania.

Zakończone pobrania = pełne pobranie pliku. Czy jest jakiś sposób na zmierzenie tego - W PHP lub czymś innym? Jeżeli tak, to na czym on mniej więcej polega (topornie, bo skomplikowanego języka i tak nie zrozumiem smile.gif)
Info: Pliki do pobrania znajdują się na subdomenie postawionej na NGINX.

Dzięki z góry za info i odpowiedzi.
peter13135
force download ?
Sephirus
Wszystko zależy od tego w jaki sposób wysyłasz użytkownikom pliki podczas pobierania. Jeżeli stoi za tym serwer to jest taka opcja w Nginx przy ustawieniu odpowiednich nagłówków aby serwer odpalił podany skrypt w momencie zakończenia pobierania. Przesyła on wtedy wielkość pobranego pliku do momentu zakończenia czyli wystarczy wtedy sprawdzić czy ta podana wielkość jest taka jak rozmiar pliku - jeśli tak to mamy pobranie całości. Niestety - nie mam dostepu do projektu w którym to robiłem a nie pamiętam dokładnie jak się to robiło - ale na pewno taka opcja jest.
splif
Dzięki Sephirus, a czy taki skrypt obciążałby w jakiś sposób serwer dodatkowo? Pytam, żeby nie było problemów np. przy 100 jednoczesnych pobraniach, lub więcej.

Czy ma ktoś jeszcze jakieś inne pomysły? W razie gdyby opisany powyżej nie zadziałał.
Sephirus
Nie nie wręcz przeciwnie. Brałem udział w dużym przedsięwzięciu gdzie X serwerów pracowało 24h umożliwiając userom ściąganie plików.

Ten system był dużo bardziej zaawansowany jeżeli chodzi o samo pobieranie bo serwery w zależności od typu użytkownika ustawiały także z jaką prędkością można pobierać plik czy właśnie rejestrowały każde pobranie (rozpoczęte, urwane przez usera, urwane przez serwer, dokończone) itd itp

Na początku daliśmy to w PHP (na próbę - wiedzieliśmy i tak że trzeba będzie to zrobić inaczej) - okazało się, że przy tej liczbie użytkowników serwer był bardzo obciążony :/ (16 procków i już nie pamietam ile ramu ;P) PHP miało wiele wad - pozwalało limitować prędkość pobierania, ale skrypty wisiały zajmując pamięć dodatkowo. Poza tym PHP miał problemu z poprawnym przechwyceniem końca pobierania - nie można było temu ufać - mimo zmuszania do dawkowania bajtów pliku PHP kończył to dużo wcześniej niż serwer. PHP kończył działanie mówiąc nam że plik został pobrany - natomiast plik cały czas jeszcze był pobierany z buforów serwera.

Przerzuciliśmy się właśnie na Nginx'a i to byl krok do przodu - tam odpowiednie wywołanie skryptu php z podaniem pliku i uprawnień skutkowało tym że w skrypcie robiło się to co miało (jakieś tam czynności - baza itp..) a następie ustawiało kilka nagłówków łącznie z przekazaniem pliku do pobrania i kończyło skrypt. Serwer obsługiwał download i w razie jego przerwania (całościowego lub częściowego) odpalał wcześniej określony skrypt PHP, analizujący przesłane mu GET'em dane. Z tego co pamiętam było to na tyle wygodne że już w nagłówkach można było (chyba) ustawić adres jaki ma zostać wywołany czyli można było dać np.: "download_end.php?file_id=123&user=456" a on dodatkowymi postami dawał dane o pliku. Opcji konfiguracji tego było pełno wink.gif

Co do porównania to jak to zaczęło działać w ten sposób to nie dość że od razu spadło obciążenie to:
- mieliśmy autentyczne logi pobierania plików (start, stop, procent, powód zerwania)
- można było obsłużyć większą liczbę uzytkowników
- serwer sam sobie ładnie radził w momencie szczytowego obciążenia - tam PHP się zapychało i wisiało

splif
Dzięki za wyczerpującą odpowiedź, spróbuję wdrożyć wspomniany sposób razem z zespołem i dam znać jak wyszło za jakiś czas smile.gif
wNogachSpisz
Co masz na myśli piszac "zakończone pobieranie"?
Czy pobranie wyłącznie ostatniego bajta przy pomocy HTTP-RANGE to też zakończone pobieranie?
A czy pobranie wszystkich bajtów poza ostatnim przy pomocy HTTP-RANGE to przerwane pobieranie?

Nie qmam ;p

Od około pół roku jestem w trakcie popełniania systemu wymiany plików.
Korzystam między innymi z PEAR:HTTP_Download.
Bardzo solidne narzędzie, używając funkcji stream_wrapper_register() mógłbyś łatwo założyć licznik przy każdorazowym pobraniu danych do bufora.
Sephirus
Ja to zrozumiałem jako pobranie całości - 0-max bajtów pliku smile.gif
wNogachSpisz
Cytat(Sephirus @ 3.11.2011, 14:09:18 ) *
Ja to zrozumiałem jako pobranie całości - 0-max bajtów pliku smile.gif

Czyli co, nie ma HTTP-RANGE?
A jeśli jest to można wytrzaskać 1GB transferu pobierając 1 bajt? tongue.gif
by_ikar
Podepnę się pod temat, jako że @Sephirus widzę coś podobnego wykonywał. Powiedz mi tylko, te pliki były na serwerze, czy serwer pośredniczył przy pobieraniu plików (ala omijanie limitów na hostach typu rapid)? Zastanawiam się nad zmianą serwera, myślę mięcy lighttpd a właśnie nginx. Jeżeli jest możliwość taka o jakiej piszesz zarówno dla pobieranych plików z serwera jak i plików przy których serwer pośredniczy, to bardzo by mi to odpowiadało, z racji tego że na własne potrzeby (swoje i swoich znajomych) chce wykonać coś, gdzie w pobieraniu serwer będzie jedynie pośredniczył. Ciekawe, będzie trzeba na ten temat więcej poczytać, bo wygląda to dość interesująco i w końcu zrezygnować z apache wink.gif
Sephirus
@by_ikar - muszę Cię rozczarować - te specjalne nagłówki i ustawienia z Nginx działają tylko na lokalnym plikach - nie ma tu mowy o pośredniczeniu :/ Twój problem trzeba obejść inaczej - wykorzystać Proxy albo mocny serwer al'a proxy - też takie rzeczy robiłem ale akurat nigdy na nginx... Co do lighttpd to uważaj na ten serwer - jest szybki owszem, ale jeżeli chodzi o konfigurowalność to leży ;/ Natrafiłem też na parę rzeczy, które dosłownie w rozmowie z twórcami zostały oznaczone jako "wiemy że to nie działa ale tak już zostanie..." Tam chodziło o coś z Perlem co było nam potrzebne do uploadu plików z tego co pamiętam. Najfajniejszy serwer na jakim pracowałem to litespeed - ale jest płatny ;P i też do wszystkiego się nie nadaje.

Nginx'a używałem do serwisu typi FS, RS, MU itp... nazwy nie podam smile.gif

EDIT: A co do apache'a to jest stary, dobry poczciwy serwer smile.gif Niestety przez jego największą zaletę (konfigurowalność) jest też strasznie wolny tongue.gif Lighttpd z kolei jest bardzo szybki ale konfiguracja jest nie miła - fajnym ich połączeniem jest właśnie Litespeed - tam mamy i jedno i drugie smile.gif Że też w apache'u nie rozwiązali lepiej kwesti plików .htaccess itp... ;P
by_ikar
Cytat
muszę Cię rozczarować - te specjalne nagłówki i ustawienia z Nginx działają tylko na lokalnym plikach - nie ma tu mowy o pośredniczeniu :/ Twój problem trzeba obejść inaczej - wykorzystać Proxy albo mocny serwer al'a proxy - też takie rzeczy robiłem ale akurat nigdy na nginx...


To zapytam się inaczej, bo w sumie jeżeli robiłeś coś podobnego, to będziesz miał jakieś pojęcie. Powiedz mi jak wysyłałeś pliki przez php, to jaki to miało narzut wydajnościowy? Nie mówię tutaj o zaraz dziesiątkach tysięcy pobierających, ale jeżeli nie będę wiedział jak to inaczej wykonać, to zwyczajnie chyba to zrobię bezpośrednio w php. Bo w sumie ma korzystać z tego średnio osób, tyle że na serwerze jest już kilka stron, ma co prawda 16gb ram 2 procesory 4 rdzeniowe, 2x dyski w raid hardware, ale nie chciałbym dojść do momentu kiedy kilka pobierań zapcha cały serwer i automatycznie zostaną odetnięte inne strony, które chodzić muszą.. Póki co jeszcze tego nie robiłem, generalnie raczej najłatwiej byłoby mi pobrać link do konkretnego pliku z takiego MU/RS/HS/FS itp za pomocą php, mam link i później będzie trzeba kombinować, z tymi featurami w nginx mnie zaciekawiłeś i w sumie po co miałbym męczyć do tego skrypty itp, skoro serwer sobie z tym bardzo dobrze poradzi wink.gif

EDIT: a co do serwera, litespeed też już brałem pod uwagę, brałem również pod uwagę cherokee w którym spodobała mi się konfiguracja przez przeglądarkę biggrin.gif fajnie to wygląda, nie jest szybszy od nginx raczej, ale na pewno przebija apache pod względem szybkości..

EDIT2: o cholera, patrzę teraz na strone cherokee i widzę że tam się wiele zmieniło! Ostatni raz patrzałem chyba z rok temu, kiedy miałem problemy z apache (wyciek pamięci) i zastanawiałem się nad zmianą serwera, ale że mnie czas naglił, zwyczajnie przeinstalowałem apache i w sumie póki co od tamtego czasu nie resetowałem go nawet wink.gif ale jak teraz patrzę na stronę cherokee to widzę że nawet wersja na windowsa powstała, wcześniej była tylko na linux/unix :| o dokumentacji nie wspomnę biggrin.gif lektura na jutro już jest wink.gif
Sephirus
Cherokee nie znam akurat ale poczytasz - może coś ciekawego znajdziesz wink.gif Co do twojego pytania jak to podźwignie PHP to możesz śmiało próbować - jeżeli serwer jest mocny tak jak pisałeś to bez problemu sobie z tym poradzi - ważne jest tylko jedno:

PHP kiepsko sobie radzi z reguły z takimi sytuacjami jak przerwane pobranie i tym podobne - kiedy user będzie chciał pobrać plik 1GB pobierze 100MB i przerwie to domyślnie PHP będzie dalej zasysał ten plik i wyrzucał go w próżnię.

Takich właśnie sytuacji trzeba się pozbyć. O co dokładnie chodzi - o wykrycie, czy użytkownik się rozłączył - musisz poczytać i pokombinować (najlepiej przetestować samemu) z takimi akcjami jak wykrycie zakończenia skryptu czy wykrycie rozłączenia przez użytkownika - (PHP ignore_user_abort albo coś takiego) - wszystko jest ładnie opisane jak działa. Co do samego wysyłania pliku do usera polecam zwyczajnie CURL'a - poradzi sobie bez problemów - sam na tym działałem i sobie radziło - potem przeszedłem na własną klasę wykorzystującą FSOCKOPEN - mniej narzutu. Musisz też potestować jakie są różnicę pomiędzy HOSTEM, twoim serwerem a przykładowym USEREM. Chodzi o to by pliki nie były zaciągane z hosta 100x szybciej niż ściągane przez użytkownika bo będą zawalać pamięć serwera - idealnym rozwiązaniem bylo by zastosowanie idei z proxy czyli - dostałem 100KB od razu je przesyłam i kasuje itd itp - nie ominiesz jednak przetrzymywania danych na serwerze w związku z tym że uzytkownik nie ma możliwośći odbierać ich z taką szybkością.

Podsumowując - zwróć uwagę na user abort i zakańczanie skryptów PHP - jeżeli to opanujesz to dla średniej liczby użytkowników to będzie hulać wink.gif Grunt aby nic nie pozostawało i nie wisiało wink.gif
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.