Учет отданного трафика на базе класса No Direct Links

Тема в разделе "PHP Pro", создана пользователем SoaringHawk, 3 окт 2010.

Статус темы:
Закрыта.
  1. SoaringHawk

    SoaringHawk Постоялец

    Регистр.:
    25 апр 2009
    Сообщения:
    61
    Симпатии:
    2
    Есть класс ndl.class

    Необходимо учитывать переданный трафик. К функции send прикрутил mysql запрос:
    PHP:
                $bufSize_portion 0;
                while ( !
    feof($fd) && (connection_status() == CON_STATUS_NORMAL) )
                {
                    
    $contents fread ($fd$this->bufSize);
                    echo 
    $contents;
                    
    //$this->updateDB(strlen($contents));
                    
    $bufSize_portion += strlen($contents);
                    
    // обновляем каждый мегабайт скачанного
                    
    if($bufSize_portion >= 1024 1024 1)
                    {
                        
    //$this->updateDB($bufSize_portion);
                        //$bufSize_portion = 0;
                    
    }
                }
                
    fclose ($fd);
                
    // финальное обновление 
                
    $this->updateDB($bufSize_portion);
                
    $bufSize_portion 0;
            }
        } 
    // end function send
        
        
    function updateDB($bufSize)
        {
            
    $this->mysql->query("UPDATE `table` SET received=received+".$bufSize." WHERE `key`='".$key."' LIMIT 1");
        }
    Но проблема в том, что по окончании передачи, "received" в базе не сходится с размером передаваемого файла. Например, файл весит 594518108 байт, а в безе записано 634203857 :confused:

    Эмпирически выяснилось, что до момента одобрения пользователем закачки, или браузер, или какой-либо DL-менеджер успевает слить в бефер определенный кусок.

    Для примера:
    Тестил с "Download Master"-ом. Добавляю ссылку на закачку, появляется менюшка выбора куда сохранять и вот в этот момент (пока я выбирал папку назначения) мастер уже загрузил 42991616 байта... После того, как я стартанул закачку он по новой закачал весь файл т.е. 594518108 байт. В итоге и получалось, что фактически было передано 637509724 байта. :(

    Может у кого появятся соображения, как можно "правильно" учитывать сколько пользователь скачал по этой временной ссылке. Это нужно для того, что бы не ограничивать клиента по времени, а ссылку "убивать" когда он полностью скачает файл.
     
  2. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    735
    Симпатии:
    261
    Вот, возьми кусок кода, который вычитает у юзера квоту непосредственно в процессе скачивания. Вроде правильно считает.
    PHP:

       $downloaded 
    0;
       
    $block 0;

       while( (!
    feof($fd)) && (connection_status()==0) && ($downloaded $size) && $block <= $user->getQuota() ) {

         
    // уменьшаем юзеру квоту на размер $block
         
    if ($block$user->setQuota($user->getQuota() - $block));

         
    $block min(1024*8$size $downloaded);
         print(
    fread($fd$block));
         
    $downloaded += $block;
         
    flush();

       }

       
    // довычитаем последний $block из квоты
       
    if (connection_status()==0)  $user->setQuota(max(0,$user->getQuota()-$block)));
    У тебя та же задача, только ты будешь не вычитать а прибавлять.
     
    SoaringHawk нравится это.
  3. diavolic

    diavolic

    Регистр.:
    17 мар 2010
    Сообщения:
    522
    Симпатии:
    102
    я бы не стал мучаться с подсчетом байтов, а ссылку просто при смене ипа того кто качает убивал бы, ну и время жизни выставил бы в неделю.
     
  4. SoaringHawk

    SoaringHawk Постоялец

    Регистр.:
    25 апр 2009
    Сообщения:
    61
    Симпатии:
    2
    Согласен, из-за буферизации и сетевых ошибок/потерь, не представляется возможным точно определить количество принятых байтов клиентом. При чем ведь важно именно принятых на стороне клиента, а не переданных со стороны сервера. :) Особенно при перехвате закачек всякими менеджерами. С мелкими файлами, бродилки успевают скинуть в свой буфер весь файл целиком, а уже после DL менеджер по сути снова качает тот же файл.

    Тут можно подойти комплексно. Для received выставить "люфт", например, в filesize*3 и время жизни ссылки в 5-7 дней (в зависимости от размера файла). И пока текущие данные по этим параметрам укладываются в установленные рамки - ссылка жива. :)

    А вот на счет ипа сложнее. Я даю пользователю возможность докачки и с динамическим ипом будет не честно убивать ссылку при его смене. :)
     
  5. diavolic

    diavolic

    Регистр.:
    17 мар 2010
    Сообщения:
    522
    Симпатии:
    102
    динамический ип это признак работы через диалап. скажи мне, вменяемый человек будет через обычный или гпрс модем качать большие файлы? соответственно писать скрипт с целью охватить и аудиторию невменяемых качеров это уже лишнее.
     
  6. SoaringHawk

    SoaringHawk Постоялец

    Регистр.:
    25 апр 2009
    Сообщения:
    61
    Симпатии:
    2
    С обычной телефонкой да, вряд ли будут качать. Хотя я в свое время на мопеде качал фильмы по 700-1400 МБ. :)

    Но а как же adsl... на сколько я знаю там в основном динамика, а скорости уже на порядок выше. Хотя привязка к ипу, конечно лучший гарант, что полученная ссылка не уйдет "по рукам", в отличие от подсчета трафика. Плюс простимулировать пользователей к переходу на качественный инет. :)

    PS Что-то отклонились немножко от темы... :)
     
  7. diavolic

    diavolic

    Регистр.:
    17 мар 2010
    Сообщения:
    522
    Симпатии:
    102
    1) адсл сейчас почти 100% это статика
    2) большинство тех кто сидит на адсл выходят в инет под общим адресом провайдера, который статический.

    вяжи к ипу, не усложняй задачу.
     
    SoaringHawk нравится это.
  8. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    735
    Симпатии:
    261
    Я не понял, что вообще требуется? Ты траф хочешь считать или ограничивать пользователей на даунлоад?

    Если траф считать, то проверяй connection_status() после fwrite(), если там все ОК - значит байты ушли и дошли. Иначе будет отвал по таймауту.

    Если тебе нужен просто антилич - то тут не нужно пускать всех через php-скрипт, намного проще будет держать динамическую RewriteMap в апаче или юзать X-Accel-Redirect в nginx. Реально, и в реализации проще, и по ресурсам не сравнить насколько экономнее.
     
Статус темы:
Закрыта.