简体   繁体   English

限制并发上传

[英]Limit concurrent uploads

I have a file upload system in my .NET Core site that allows for a user to upload as many files as they want at a time directly to an S3 bucket.我的 .NET Core 站点中有一个文件上传系统,允许用户一次将任意数量的文件直接上传到 S3 存储桶。 A user can upload 1 or many files.一个用户可以上传 1 个或多个文件。 The problem that I am having is that when uploading, lets say 1,000 files, the browser does not like to create that many connections and more often than not, files routinely fail to upload.我遇到的问题是,当上传 1,000 个文件时,浏览器不喜欢创建那么多连接,而且通常情况下,文件通常无法上传。 Even with retries enabled, those retries tend to fail since the browser only allows a certain number of concurrent connections.即使启用了重试,这些重试也往往会失败,因为浏览器只允许一定数量的并发连接。 Even worse the browser will lock up.更糟糕的是浏览器会锁定。

What I am looking to do is place the files into a queue and only allow 20 files to be actually uploading at any given time (Think of how FileZilla queues items to upload).我想要做的是将文件放入一个队列中,并且在任何给定时间只允许实际上传 20 个文件(想想 FileZilla 如何对要上传的项目进行排队)。 When a file completes, a new files is added until the queue is exhausted.当一个文件完成时,会添加一个新文件,直到队列用完为止。 This way the browser is only creating the connections it needs.这样浏览器只创建它需要的连接。 I already have it so AutoUpload is set to False and I can place the files into an array to process but the uploadSelectEvent.sender.upload() method enables upload for everything.我已经有了它,所以AutoUpload设置为False ,我可以将文件放入数组中进行处理,但uploadSelectEvent.sender.upload()方法可以上传所有内容。

Is there a way to pause all the uploads prior to enabling the upload so I can then resume them as needed?有没有办法在启用上传之前暂停所有上传,以便我可以根据需要恢复它们? Is there a better way to handle this?有没有更好的方法来处理这个问题?

I was able to figure this out on my own.我能够自己解决这个问题。 Here is how (note this will require some modification to work for your own code and my not be a pure copy and paste answer):这是方法(请注意,这将需要一些修改才能适用于您自己的代码,我不是纯粹的复制和粘贴答案):

Create an array to hold some data:创建一个数组来保存一些数据:

/** Files currently uploading */
const uploadQueue: any[] = [];

Capture the FileSuccess event and add this捕获FileSuccess事件并添加此

    // Check the size of the queue
    if (uploadQueue.length < 20) {
        const that = (uploadSuccessEvent.sender as any);
        const module = that._module;
        const upload = module.upload;

        $(".k-file").each((i, x) => {
            //console.log(i, x);
            if (uploadQueue.length < 20) {
                const fileEntry = $(x);
                const started = fileEntry.is(".k-file-progress, .k-file-success, .k-file-error");
                const hasValidationErrors = upload._filesContainValidationErrors(fileEntry.data("fileNames"));

                if (!started && !hasValidationErrors) {
                    uploadQueue.push(fileEntry.data("fileNames")[0].uid);
                    //console.log("fileEntry", fileEntry.data("fileNames")[0].uid);

                    // Start the upload process
                    module.performUpload(fileEntry);
                }
            }
            else { return; }
        });
    }

Create a new function to handle the upload queue:创建一个新函数来处理上传队列:

/**
 * Adds the file to the upload queue and starts the upload.
 * Other files will be loaded via the on success event.
 * @param uploadSelectEvent Select event object.
 */
function queueUpload(uploadSelectEvent: kendo.ui.UploadSelectEvent) {
    //console.log("uploadSelectEvent", uploadSelectEvent);

    // Check the size of the queue
    if (uploadQueue.length < 20) {
        // Start the upload process
        const that = (uploadSelectEvent.sender as any);
        const module = that._module;
        const upload = module.upload;

        //uploadSelectEvent.files.forEach((file, i) => { console.log(i, file); if (uploadQueue.length < 20) { uploadQueue.push(file.uid); } });

        $(".k-file").each((i, x) => {
            //console.log(i, x);
            if (uploadQueue.length < 20) {
                const fileEntry = $(x);
                const started = fileEntry.is(".k-file-progress, .k-file-success, .k-file-error");
                const hasValidationErrors = upload._filesContainValidationErrors(fileEntry.data("fileNames"));

                if (!started && !hasValidationErrors) {
                    uploadQueue.push(fileEntry.data("fileNames")[0].uid);
                    module.performUpload(fileEntry);
                }
            }
            else { return; }
        });
    }
}

Capture the FileSelect event and pass the event to queueUpload .捕获FileSelect事件并将该事件传递给queueUpload

In the end, you should be limiting the concurrent uploads to 20 at once.最后,您应该一次将并发上传限制为 20。 It still allows dragging 100's or 1000's of files into the browser (it may still lock up for a sec) but it will only create up to 20 connections at a time.它仍然允许将 100 或 1000 个文件拖入浏览器(它可能仍会锁定一秒钟),但一次最多只能创建 20 个连接。 This may not be the most ideal code but it worked for my situation.这可能不是最理想的代码,但它适用于我的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM