5赞
866
当前位置:  开发笔记 > 编程语言 > 正文

.NET或.NETCoreWebAPi基于tus协议实现断点续传的示例

这篇文章主要介绍了.NET或.NETCoreWebAPi基于tus协议实现断点续传的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

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

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

基于tus协议tusdotnet方案基本demo

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

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


接下来进入后台,首先安装对应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()));

在脚本中我们看到有个endpoint属性,此属性表示上传到服务器的上传结点地址,因为在上到服务器时我们可能需对此请求进行额外处理,比如元数据中的文件名是否已提供等等,所以我们在使用结点映射时,添加对上述结点名称的映射,如下:

endpoints.MapGet("/files/{fileId}", DownloadFileEndpoint.HandleRoute);

该映射第二个参数为RequestDelegate,这个参数用过.NET Core的童鞋都知道,这里我是直接拷贝该包的路由实现,如下:

public static class DownloadFileEndpoint
{
  public static async Task HandleRoute(HttpContext context)
  {
    var cOnfig= context.RequestServices.GetRequiredService();

    if (!(config.Store is ITusReadableStore store))
    {
      return;
    }

    var fileId = (string)context.Request.RouteValues["fileId"];
    var file = await store.GetFileAsync(fileId, context.RequestAborted);

    if (file == null)
    {
      context.Response.StatusCode = 404;
      await context.Response.WriteAsync($"File with id {fileId} was not found.", context.RequestAborted);
      return;
    }

    var fileStream = await file.GetContentAsync(context.RequestAborted);
    var metadata = await file.GetMetadataAsync(context.RequestAborted);

    context.Response.COntentType= GetContentTypeOrDefault(metadata);
    context.Response.COntentLength= fileStream.Length;

    if (metadata.TryGetValue("name", out var nameMeta))
    {
      context.Response.Headers.Add("Content-Disposition",
        new[] { $"attachment; filename=\"{nameMeta.GetString(Encoding.UTF8)}\"" });
    }

    using (fileStream)
    {
      await fileStream.CopyToAsync(context.Response.Body, 81920, context.RequestAborted);
    }
  }

  private static string GetContentTypeOrDefault(Dictionary metadata)
  {
    if (metadata.TryGetValue("contentType", out var contentType))
    {
      return contentType.GetString(Encoding.UTF8);
    }

    return "application/octet-stream";
  }
}

文件上传大小限制说明

我们知道无论是.NET还是.NET Core对于文件上传大小都有默认限制大小,这里对.NET Core中文件大小各种环境配置做一个统一说明,如果你将.NET Core寄宿在IIS上运行,那么请修改web.config配置文件大小限制


 
  
   //若不配置,默认是28.6兆
   
  
 

如果在开发环境默认使用IIS运行应用程序,请通过如下根据实际情况配置文件上传大小

services.Configure(optiOns=>
 {
   options.MaxRequestBodySize = int.MaxValue;
 });

如果程序运行在Kestrel服务器,那么请通过如下根据实际情况配置文件上传大小

services.Configure(optiOns=>
{
   //若不配置,默认是30兆(没记错的话)
   options.Limits.MaxRequestBodySize = int.MaxValue; 
});

如果是通过表单上传文件,那么请通过如下根据实际情况配置文件上传大小

services.Configure(x =>
{
   x.ValueLengthLimit = int.MaxValue;
  //如果不配置,默认是128兆(没记错的话)
   x.MultipartBodyLengthLimit = int.MaxValue; 
   x.MultipartHeadersLengthLimit = int.MaxValue;
});

总结

为了更好体验可以再加上当前网络宽带情况或剩余多少分钟,更详细内容请参考:https://github.com/tusdotnet/tusdotnet、https://github.com/tus/tus-js-client,关于大文件上传处理到此结束,希望对那些苦苦寻找最终解决方案而无助的童鞋们提供最佳轮子,谢谢。

到此这篇关于.NET或.NET Core Web APi基于tus协议实现断点续传的示例的文章就介绍到这了,更多相关.NET tus断点续传内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

推荐阅读
  • 从简单的初学者平台到专家级开发工作台,每个Python高手(Pythonista)都有一个IDE。这里有七个我们精心挑选的PythonIDE,规模按最小到最大排列,他们也应该在你的雷达上。 ... [详细]
  • Pandas和Numpy大家都不陌生了,代码运行后数据都加载到RAM中,如果数据集特别大,我们就会看到内存飙升。但有时要处理的数据并不适合RAM,这时候Dask来了。 ... [详细]
  • urllib是Python中用来处理URL的工具包,本文利用该工具包进行爬虫开发讲解,毕竟爬虫应用开发在Web互联网数据采集中十分重要。文章目录urllibrequest模块访问URLRequest类其他类parse模块解析URL转义URLrobots.txt文件 ... [详细]
  • “.gitignore”文件作用是可以忽略原来制定的规则,也可以根据自己的需要制定自己的规则。使用git过程中,总会有些文件无需纳入git的管理,也不希望它们出现在未跟踪文件列表,这时可以使用“.gitignore”文件自动忽略这些文件。 ... [详细]
  • go语言开发时经常会遇到无法下载某些第三方包,原因是golang.org被墙了。那么该如何避免遇到这种情况呢?本文就来为大家介绍一下如何解决使用goget命令被墙的问题。 ... [详细]
  • 解决Go升级到1.14后无法Debug
    Debug对一个程序员是多么的重要,然后在升级了go1.14后,我的debug却使用不了了,这就很尴尬。遇到问题解决问题。 ... [详细]
  • go语言乱码的解决办法:首先下载第三方软件包;然后解压出来,并将文件夹改为text;接着在go安装路径的src下创建文件夹,并将text文件夹放在其中;最后完成编码转换即可。 ... [详细]
  • ​下面由golang教程栏目给大家介绍基于GO语言框架Gin开发的MVC轮子框架:GinLaravel,希望对需要的朋友有所帮助! ... [详细]
  • 本篇文章主要介绍了asp.netMVC下使用rest的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ... [详细]
  • 本篇将和大家分享的丝.NetCore下载文件,常见的下载有两种:A标签直接指向下载文件地址和post或get请求后台输出文件流的方式,本篇也将围绕这两种来分享;如果对您有好的帮助,请多多支持。 ... [详细]
devbox
昙檀禅潺_162
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4