.NET或.NET Core Web APi基于tus协议实现断点续传的示

前两天我采用技巧式方案基本实现大文件分片上传,这里只是重点在于个人思路和亲身实践,若在实际生产环境要求比较高的话肯定不行,仍存在一些问题需要深入处理,本文继续在之前基础上给出基于tus协议的轮子方案,本打算再次尝试利用.NET Core实现此协议,但在github上一搜索早在2016年就已有此协议对应的.NET和.NET Core方案,并且一直更新到最近的.NET Core 3.x版本,完全满足各位所需,本文是我写出的一点demo,demo地址:https://github.com/wangpengxpy/tus-demo

基于tus协议实现断点续传演示

.NET或.NET Core Web APi基于tus协议实现断点续传的示

基于tus协议tusdotnet方案基本demo

关于此协议实现原理这里不做阐述,请参照上述github地址自行了解,本文只是给出.NET Core方案下的基本demo,我们上传一个大文件然后通过进度显示上传进度以及对上传可暂停可继续,专业点讲就是断点续传,首先肯定是引入tus脚本和需要用到的bootstrap样式,我们将进度条默认隐藏,当上传时才显示,所以我们给出如下HTML。

<div> <div> <div></div> <div> <div role="progressbar" aria-valuemin="0" aria-valuemax="100"> <span></span> </div> </div> </div> <div> <div> <input type="file" /> </div> </div> <div> <div> <input type="submit" value="上传" /> <input type="button" value="暂停" /> <input type="button" value="继续" /> </div> </div> </div>

.NET或.NET Core Web APi基于tus协议实现断点续传的示

接下来就是使用引入的tus脚本,也没什么太多要讲解的,直接上代码,这里稍微注意的是在如下元数据(metadata)属性对象定义给出实际文件名,便于在后台最终将上传的文件转换为目标文件,至少得知道文件扩展名,对吧。

<script type="text/javascript"> $(function () { var upload; //上传 $('#submit').click(function () { $('#progress-group').show(); var file = $('#file')[0].files[0]; // 创建tus上传对象 upload = new tus.Upload(file, { // 文件服务器上传终结点地址设置 endpoint: "files/", // 重试延迟设置 retryDelays: [0, 3000, 5000, 10000, 20000], // 附件服务器所需的元数据 metadata: { name: file.name, contentType: file.type || 'application/octet-stream', emptyMetaKey: '' }, // 回调无法通过重试解决的错误 onError: function (error) { console.log("Failed because: " + error) }, // 上传进度回调 onProgress: onProgress, // 上传完成后回调 onSuccess: function () { console.log("Download %s from %s", upload.file.name, upload.url) } }) upload.start() }); //暂停 $('#pause').click(function () { upload.abort() }); //继续 $('#continue').click(function () { upload.start() }); //上传进度展示 function onProgress(bytesUploaded, bytesTotal) { var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2); $('#progress').attr('aria-valuenow', percentage); $('#progress').css('width', percentage + '%'); $('#percentage').html(percentage + '%'); var uploadBytes = byteToSize(bytesUploaded); var totalBytes = byteToSize(bytesTotal); $('#size').html(uploadBytes + 'https://www.jb51.net/' + totalBytes); } //将字节转换为Byte、KB、MB等 function byteToSize(bytes, separator = '', postFix = '') { if (bytes) { const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.min(parseInt(Math.floor(Math.log(bytes) / Math.log(1024)).toString(), 10), sizes.length - 1); return `${(bytes / (1024 ** i)).toFixed(i ? 1 : 0)}${separator}${sizes[i]}${postFix}`; } return 'n/a'; } }); </script>

接下来进入后台,首先安装对应tus协议实现包,如下:

.NET或.NET Core Web APi基于tus协议实现断点续传的示

接下来则是添加tus中间件,说白了就是对tus的配置,各种配置都可满足你所需,这里我只实现了文件上传完成后将上传文件转换为目标文件的处理,紧接着将如下实现tus配置以单例形式注入即可

private DefaultTusConfiguration CreateTusConfiguration(IServiceProvider serviceProvider) { var env = (IWebHostEnvironment)serviceProvider.GetRequiredService(typeof(IWebHostEnvironment)); //文件上传路径 var tusFiles = Path.Combine(env.WebRootPath, "tusfiles"); return new DefaultTusConfiguration { UrlPath = "/files", //文件存储路径 Store = new TusDiskStore(tusFiles), //元数据是否允许空值 MetadataParsingStrategy = MetadataParsingStrategy.AllowEmptyValues, //文件过期后不再更新 Expiration = new AbsoluteExpiration(TimeSpan.FromMinutes(5)), //事件处理(各种事件,满足你所需) Events = new Events { //上传完成事件回调 OnFileCompleteAsync = async ctx => { //获取上传文件 var file = await ctx.GetFileAsync(); //获取上传文件元数据 var metadatas = await file.GetMetadataAsync(ctx.CancellationToken); //获取上述文件元数据中的目标文件名称 var fileNameMetadata = metadatas["name"]; //目标文件名以base64编码,所以这里需要解码 var fileName = fileNameMetadata.GetString(Encoding.UTF8); var extensionName = Path.GetExtension(fileName); //将上传文件转换为实际目标文件 File.Move(Path.Combine(tusFiles, ctx.FileId), Path.Combine(tusFiles, $"{ctx.FileId}{extensionName}")); } } }; }

然后获取并使用上述添加的tus配置服务

app.UseTus(httpContext => Task.FromResult(httpContext.RequestServices.GetService<DefaultTusConfiguration>()));

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5fceca9086757a3958d2e9bccd5655ec.html