這篇文章主要講解了“.NET或.NET Core Web APi基于tus協(xié)議實現(xiàn)斷點續(xù)傳的講解”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“.NET或.NET Core Web APi基于tus協(xié)議實現(xiàn)斷點續(xù)傳的講解”吧!
成都創(chuàng)新互聯(lián)公司:從2013年成立為各行業(yè)開拓出企業(yè)自己的“網(wǎng)站建設(shè)”服務(wù),為近1000家公司企業(yè)提供了專業(yè)的成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計和網(wǎng)站推廣服務(wù), 按需定制由設(shè)計師親自精心設(shè)計,設(shè)計的效果完全按照客戶的要求,并適當(dāng)?shù)奶岢龊侠淼慕ㄗh,擁有的視覺效果,策劃師分析客戶的同行競爭對手,根據(jù)客戶的實際情況給出合理的網(wǎng)站構(gòu)架,制作客戶同行業(yè)具有領(lǐng)先地位的。前言
前兩天我采用技巧式方案基本實現(xiàn)大文件分片上傳,這里只是重點在于個人思路和親身實踐,若在實際生產(chǎn)環(huán)境要求比較高的話肯定不行,仍存在一些問題需要深入處理,本文繼續(xù)在之前基礎(chǔ)上給出基于tus協(xié)議的輪子方案,本打算再次嘗試利用.NET Core實現(xiàn)此協(xié)議,但在github上一搜索早在2016年就已有此協(xié)議對應(yīng)的.NET和.NET Core方案,并且一直更新到最近的.NET Core 3.x版本,完全滿足各位所需,本文是我寫出的一點demo,demo地址:https://github.com/wangpengxpy/tus-demo
基于tus協(xié)議實現(xiàn)斷點續(xù)傳演示
基于tus協(xié)議tusdotnet方案基本demo
關(guān)于此協(xié)議實現(xiàn)原理這里不做闡述,請參照上述github地址自行了解,本文只是給出.NET Core方案下的基本demo,我們上傳一個大文件然后通過進度顯示上傳進度以及對上傳可暫停可繼續(xù),專業(yè)點講就是斷點續(xù)傳,首先肯定是引入tus腳本和需要用到的bootstrap樣式,我們將進度條默認隱藏,當(dāng)上傳時才顯示,所以我們給出如下HTML。
接下來就是使用引入的tus腳本,也沒什么太多要講解的,直接上代碼,這里稍微注意的是在如下元數(shù)據(jù)(metadata)屬性對象定義給出實際文件名,便于在后臺最終將上傳的文件轉(zhuǎn)換為目標文件,至少得知道文件擴展名,對吧。
接下來進入后臺,首先安裝對應(yīng)tus協(xié)議實現(xiàn)包,如下:
接下來則是添加tus中間件,說白了就是對tus的配置,各種配置都可滿足你所需,這里我只實現(xiàn)了文件上傳完成后將上傳文件轉(zhuǎn)換為目標文件的處理,緊接著將如下實現(xiàn)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), //元數(shù)據(jù)是否允許空值 MetadataParsingStrategy = MetadataParsingStrategy.AllowEmptyValues, //文件過期后不再更新 Expiration = new AbsoluteExpiration(TimeSpan.FromMinutes(5)), //事件處理(各種事件,滿足你所需) Events = new Events { //上傳完成事件回調(diào) OnFileCompleteAsync = async ctx => { //獲取上傳文件 var file = await ctx.GetFileAsync(); //獲取上傳文件元數(shù)據(jù) var metadatas = await file.GetMetadataAsync(ctx.CancellationToken); //獲取上述文件元數(shù)據(jù)中的目標文件名稱 var fileNameMetadata = metadatas["name"]; //目標文件名以base64編碼,所以這里需要解碼 var fileName = fileNameMetadata.GetString(Encoding.UTF8); var extensionName = Path.GetExtension(fileName); //將上傳文件轉(zhuǎn)換為實際目標文件 File.Move(Path.Combine(tusFiles, ctx.FileId), Path.Combine(tusFiles, $"{ctx.FileId}{extensionName}")); } } }; }
然后獲取并使用上述添加的tus配置服務(wù)
app.UseTus(httpContext => Task.FromResult(httpContext.RequestServices.GetService()));
在腳本中我們看到有個endpoint屬性,此屬性表示上傳到服務(wù)器的上傳結(jié)點地址,因為在上到服務(wù)器時我們可能需對此請求進行額外處理,比如元數(shù)據(jù)中的文件名是否已提供等等,所以我們在使用結(jié)點映射時,添加對上述結(jié)點名稱的映射,如下:
endpoints.MapGet("/files/{fileId}", DownloadFileEndpoint.HandleRoute);
該映射第二個參數(shù)為RequestDelegate,這個參數(shù)用過.NET Core的童鞋都知道,這里我是直接拷貝該包的路由實現(xiàn),如下:
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中文件大小各種環(huán)境配置做一個統(tǒng)一說明,如果你將.NET Core寄宿在IIS上運行,那么請修改web.config配置文件大小限制
//若不配置,默認是28.6兆
如果在開發(fā)環(huán)境默認使用IIS運行應(yīng)用程序,請通過如下根據(jù)實際情況配置文件上傳大小
services.Configure(options => { options.MaxRequestBodySize = int.MaxValue; });
如果程序運行在Kestrel服務(wù)器,那么請通過如下根據(jù)實際情況配置文件上傳大小
services.Configure(options => { //若不配置,默認是30兆(沒記錯的話) options.Limits.MaxRequestBodySize = int.MaxValue; });
如果是通過表單上傳文件,那么請通過如下根據(jù)實際情況配置文件上傳大小
services.Configure(x => { x.ValueLengthLimit = int.MaxValue; //如果不配置,默認是128兆(沒記錯的話) x.MultipartBodyLengthLimit = int.MaxValue; x.MultipartHeadersLengthLimit = int.MaxValue; });
總結(jié)
為了更好體驗可以再加上當(dāng)前網(wǎng)絡(luò)寬帶情況或剩余多少分鐘,更詳細內(nèi)容請參考:https://github.com/tusdotnet/tusdotnet、https://github.com/tus/tus-js-client,關(guān)于大文件上傳處理到此結(jié)束,希望對那些苦苦尋找最終解決方案而無助的童鞋們提供很好輪子,謝謝。
感謝各位的閱讀,以上就是“.NET或.NET Core Web APi基于tus協(xié)議實現(xiàn)斷點續(xù)傳的講解”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對.NET或.NET Core Web APi基于tus協(xié)議實現(xiàn)斷點續(xù)傳的講解這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!