ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Докачка при аплоаде



Дмитрий Дедюхин пишет:
Да, возможна.

Валерий, я видел у вас в гите экспериментальную ветку с поддержкой дозакачки, 
но так и не сподобился посмотреть в код.
Можете в двух словах рассказать, как это реализовано в аплоад-модуле?
В браузере стандартный input type=file никак не может это реализовать, там 
нельзя начать загружать файл по смещению. Вы рассчитываете на плагины (Flash 
или Silverlight)?

Нет, загрузку файлов по частям можно реализовать используя Google Gears и Blob API. Приблизительно так:

var fileList = {};

function browse() {
    var desktop = google.gears.factory.create('beta.desktop');

    desktop.openFiles(function(files) {
        for (var i=0; i < files.length; i++) {
            if(!fileList[files[i].name]) {

                fileList[files[i].name] = {
                    filename: files[i].name,
                    uploaded: 0,
                    length: files[i].blob.length,
                    blob: files[i].blob,
                    sessionkey: sessionkey(),
                };
            }
        }
$('#upload').html('<a href="#upload" onclick="return upload();">Upload</a>');
    });
}

function upload() {
    var chunkLength, chunk;

    for(file in mylist) {
        if((file.uploaded < file.length && !file.error)) {
            chunkLength = min(file.uploaded + CHUNK_BYTES, file.length);
chunk = file.blob.slice(file.uploaded, (chunkLength - file.uploaded)); sendChunk(file, chunk, file.uploaded, chunkLength, file.length, file.sessionkey);
        }
    }
}

function sendChunk(entry, chunk, start, end, total, sessionkey {

    var req = google.gears.factory.create('beta.httprequest');

    req.open('POST', '/upload');

    var headers = {
'Content-Disposition': 'attachment; name="'+sessionkey+'"; filename="'+file+'"',
        'Content-Type': 'application/octet-stream',
        'Content-Range': 'bytes '+start+'-'+end+'/'+total
    };
for(var h in headers) { if(headers.hasOwnProperty(h)) { req.setRequestHeader(h, headers[x]); } }

    req.onreadystatechange = function(){
        if(req.readyState == 4 && req.status == 205) {
            entry.uploaded = end;
            upload();
        }
    }
    req.send(chunk);
}

Далее:

<div>
    <a href="#select" onclick="return browse();">Select files</a>
    <span id="upload"></span>
</div>

К сожалению, оригинальный клиентский код не мой, поэтому выше приведена только приблизительная реализация.

На сервере нужен upload module из следующей ветки:

http://github.com/vkholodkov/nginx-upload-module/tree/partial-upload

Директива upload_state_store задает каталог, в котором модуль будет сохранять состояние загрузки. А именно, список сегментов файла, которые полностью загружены. Таким образом, загрузки возобновляемы между перезапусками nginx.

Принцип взаимодействия с бакэндом аналогичный.

Эта ветка экспериментальная, поэтому могут возникнуть всевозможные неожиданности.

--
Best regards,
Valery Kholodkov

_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://nginx.org/mailman/listinfo/nginx-ru


 




Copyright © Lexa Software, 1996-2009.