Выгрузка больших двоичных объектов в блоки с использованием REST API истекает во втором фрагменте

ПРИМЕЧАНИЕ. Может ли кто-нибудь дать мне пример строки SAS (с добавлением информации о блоке в правой области), которую необходимо отправить в хранилище BLOB-объектов Azure? Я думаю, что это проблема, которая у меня возникла. Мне нужно выяснить порядок uri, ключа и т. Д. В строке, которая отправляется в Azure с каждым блоком.

Я пытаюсь получить ключ SAS из службы, изменить строковый ключ, чтобы azure знал, что я отправляю блоки, а затем отправить отдельные блоки файла с ключом sas из веб-клиента. . Я разбиваю каждый файл на блоки по 2 МБ и отправляю эти блоки по 2 МБ с библиотекой JavaScript за раз. Таким образом, каждый «файл» в приведенном ниже коде - это всего лишь фрагмент файла размером 2 МБ.

ПРОБЛЕМА: я могу успешно получить ключ SAS от службы, изменить ключ так, чтобы в нем была информация о блоке, отправить ПЕРВЫЙ блок, а затем получить ответ от сервера хранилища BLOB-объектов. Однако, когда я отправляю второй фрагмент, запрос потока в хранилище BLOB-объектов зависает, а затем в конечном итоге истекает время ожидания. Похоже, что тайм-аут произошел специально для второго запроса потока в хранилище BLOB-объектов. Вот этот фрагмент кода:

КОД ВЕБ-КЛИЕНТА СЕРВЕРА:

    using (Stream requestStream = request.GetRequestStream())
    {
        inputStream.CopyTo(requestStream, file.ContentLength);
    }

Что могло вызвать тайм-аут второго фрагмента? Может быть, окно для ключа закрывается слишком рано? Ниже мой код и несколько скриншотов:

    private void WriteToBlob(HttpPostedFileBase file, string BlockId, FileProp fp)
    {
        var inputStream = file.InputStream;

        Microsoft.WindowsAzure.StorageCredentialsSharedAccessSignature credentials =
            new Microsoft.WindowsAzure.StorageCredentialsSharedAccessSignature(fp.facct);


        string queryString = (new Uri(fp.folderName)).Query;

        string RequestUri = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}/{1}{2}&comp=block&blockid={3}",
            fp.folderName, fp.fileName, queryString, Convert.ToBase64String(Encoding.UTF8.GetBytes(BlockId)));

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(RequestUri);
        request.Method = "PUT";
        request.ContentLength = inputStream.Length;
        using (Stream requestStream = request.GetRequestStream())
        {
            inputStream.CopyTo(requestStream, file.ContentLength);
        }

    }

КОД JAVASCRIPT, ОТПРАВЛЯЮЩИЙ ЧАНКИ КЛИЕНТУ ВЕБ-СЕРВЕРА:

        var running = 0;
    var chunksize = (Modernizr.blobconstructor) ? uploadChunkSize : null;    //if browser support Blob API
    window.xhrPool = [];
    $('#fileupload').fileupload({
        url: url,
        //formData: [{ name: 'param1', value: 1 }, { name: 'param2', value: 2}],
        singleFileUploads: true, //each file is using an individual XHR request
        //limitMultiFileUploads: 2, //This option is ignored, if singleFileUploads is set to true.
        multipart: true,
        maxChunkSize: chunksize, //server side is in streaming mode
        sequentialUploads: true, //Set this option to true to issue all file upload requests in a sequential order instead of simultaneous requests.
        dataType: 'json',
        autoUpload: true,
        //acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
        progressInterval: 100,
        bitrateInterval: 100,
        maxFileSize: uploadFileSizeLimit
    }).on('fileuploadadd', function (e, data) {

        var filename = data.files[0].name;
        var filesize = data.files[0].size;
        if (filesize == 0) {
            var zeroSizeErrMsg = sceneLayoutService.format('This file {filename} is empty please select files again without it. ', { filename: filename });
            sceneLayoutService.showErrorDialog(zeroSizeErrMsg);
            return;
        }

        if (window.availableStorageSize != null && window.availableStorageSize != '') {
            if (filesize > window.availableStorageSize) {
                var overSizeErrMsg = sceneLayoutService.format('File size of {filename} exceeds available storage space in your cloud drive. ', { filename: filename });
                sceneLayoutService.showErrorDialog(overSizeErrMsg);
                return;
            }
        } else {
            alert('Unable to retrieve the storage usage.');
        }

        data.jqXHR = data.submit();
        window.xhrPool.push(data.jqXHR);
        sceneLayoutService.addFileToProgressDialog(data, cancelButton);

    }).on('fileuploadprocessalways', function (e, data) {

    }).on('fileuploadprogressall', function (e, data) {

    }).on('fileuploadsubmit', function (e, data) {

        var filesize = data.files[0].size;
        if (filesize == 0) {
            return false;
        }

        if (window.availableStorageSize != null && window.availableStorageSize != '') {
            if (filesize > window.availableStorageSize) {
                return false;
            }
        }
        $('#dlgProgress').parent().show();
        running++;
        sceneLayoutService.showProgressDialog('Uploading files to ' + currentUser + '\'s Cloud Storage ...', abortAllUploads);
        return true;

    }).on('fileuploaddone', function (e, data) {

        running--;
        updateStorageQuota(function () {
            var usedStorageSize = (window.usedStorageSize != null) ? bytesToSize(window.usedStorageSize, 2) : 0;
            var totalStorageSize = (window.totalStorageSize != null) ? bytesToSize(window.totalStorageSize, 2) : 0;
            var usageFooterStr = sceneLayoutService.format("Using {used} of {total} (%)", { used: usedStorageSize, total: totalStorageSize });
            $('div.dlgProgressFooter').text(usageFooterStr);
        });


        var docGridUrl = window.baseUrl + '/CloudStorage/ChangePage?page=1&rand=' + sceneLayoutService.getRandomString(4);
        $('#docGridPartial').load(docGridUrl, function () {
            grid.init({
                pageNumber: 1,
                url: window.baseUrl + '/CloudStorage/ChangePage',
                sortColumn: '',
                sortDirection: ''
            });
        });

        sceneLayoutService.updateFileUploadFinalStatus(data, 'done');

        if (!data.result.success) {
            debugger;
            var errMsg = "";
            if (data.result != null) {
                if (data.result.message != null) {
                    errMsg += data.result.message;
                }
                if (data.result.error != null)
                    errMsg += data.result.error;
            }
            sceneLayoutService.showErrorDialog(errMsg);
        }
        window.removeXHRfromPool(data);

        if (running == 0) {
            $('#dlgProgress').parent().hide();
            $('#progresses').empty();
        }
    }).on('fileuploadfail', function (e, data) {
        running--;

        sceneLayoutService.updateFileUploadFinalStatus(data, 'fail');

        window.removeXHRfromPool(data);

        if (running == 0) {
            $('#dlgProgress').parent().hide();
            $('#progresses').empty();
        }
    }).on('fileuploadprogress', function (e, data) {

        //XHR upload onProgress event not fired at server-defined intervals/not supported in IE8 and IE9,
        //will be supported in IE10 in terms of XMLHttpRequest Level 2 specification, http://caniuse.com/xhr2
        sceneLayoutService.updateFileUploadProgress(data);
    });

введите описание изображения здесь

введите описание изображения здесь


person TheDude    schedule 09.08.2013    source источник
comment
Быстрые вопросы - правильно ли я понимаю, что каждый опубликованный файл загружается как отдельный блок? Не связано с вашей ошибкой, но я заметил, что вы передаете идентификатор блока в виде простой строки. Обратите внимание, что вам нужно будет преобразовать его в строку в кодировке Base64, а затем передать ее как URL-адрес.   -  person Gaurav Mantri    schedule 10.08.2013
comment
Я разбиваю каждый файл на блоки по 2 МБ и отправляю эти блоки по 2 МБ с библиотекой JavaScript за раз. Таким образом, каждый файл в приведенном выше коде - это всего лишь фрагмент файла размером 2 МБ. Что касается BlockId, у меня изначально было установлено значение Base64: Convert.ToBase64String (Encoding.UTF8.GetBytes (BlockId)). Я просто пробовал без преобразования, но все еще сталкивался с той же проблемой.   -  person TheDude    schedule 10.08.2013
comment
Спасибо за разъяснение. Можно ли будет поделиться кодом для фрагментации файла на стороне клиента в JavaScript? Используете ли вы для этого HTML 5 File API? Я постараюсь воссоздать проблему со своей стороны.   -  person Gaurav Mantri    schedule 10.08.2013
comment
Я использую библиотеку загрузки Javascript blueimp. Я включу код для этого.   -  person TheDude    schedule 10.08.2013
comment
Привет, @TheDude, спасибо, что поделились своим кодом для этого решения! В настоящее время я использую загрузчик Silverlight для этой цели (загрузка mp3, не желая загружать наш сервер), но надеялся получить решение html / javascript. Похоже, blueimp отвечает всем требованиям. То, что вы поделились выше, в значительной степени является вашим полным (настроенным) кодом javascript для этой работы?   -  person Nicholas Petersen    schedule 26.11.2013


Ответы (1)


Проблема решена. Оказывается, формат URI SAS был неправильным. Вот как должен выглядеть Sas URI (в моем случае для контейнера):

http://container_uri/filename?key
person TheDude    schedule 14.08.2013