.NET或.NET Core Web APi基于tus协议实现断点续传
【導讀】前兩天我采用技巧式方案基本實現大文件分片上傳,這里只是重點在于個人思路和親身實踐,若在實際生產環境要求比較高的話肯定不行,仍存在一些問題需要深入處理,本文繼續在之前基礎上給出基于tus協議的輪子方案,本打算再次嘗試利用.NET Core實現此協議,但在github上一搜索早在2016年就已有此協議對應的.NET和.NET Core方案,并且一直更新到最近的.NET Core 3.x版本,完全滿足各位所需,本文是我寫出的一點demo。
基于tus協議實現斷點續傳演示
基于tus協議前端腳本
關于此協議實現原理這里不做闡述,請參照上述github地址自行了解,本文只是給出.NET Core方案下的基本demo,我們上傳一個大文件然后通過進度顯示上傳進度以及對上傳可暫停可繼續,專業點講就是斷點續傳,首先肯定是引入tus腳本和需要用到的bootstrap樣式,我們將進度條默認隱藏,當上傳時才顯示,所以我們給出如下HTML。
<div?class="form-horizontal"?style="margin-top:80px;"><div?class="form-group"?id="progress-group"?style="display:none;"><div?id="size"></div><div?class="progress"><div?id="progress"?class="progress-bar?progress-bar-success?progress-bar-animated?progress-bar-striped"?role="progressbar"aria-valuemin="0"?aria-valuemax="100"><span?id="percentage"></span></div></div></div><div?class="form-group"><div?class="col-md-10"><input?name="file"?id="file"?type="file"?/></div></div><div?class="form-group"><div?class="col-md-offset-2?col-md-10"><input?type="submit"?id="submit"?value="上傳"?class="btn?btn-success"?/><input?type="button"?id="pause"?value="暫停"?class="btn?btn-danger"?/><input?type="button"?id="continue"?value="繼續"?class="btn?btn-info"?/></div></div> </div>接下來就是使用引入的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?+?'/'?+?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協議tusdotnet
接下來進入后臺,首先安裝對應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}"));}}}; }</script>然后獲取并使用上述添加的tus配置服務
在腳本中我們看到有個endpoint屬性,此屬性表示上傳到服務器的上傳結點地址,因為在上到服務器時我們可能需對此請求進行額外處理,比如元數據中的文件名是否已提供等等,所以我們在使用結點映射時,添加對上述結點名稱的映射,如下
該映射第二個參數為RequestDelegate,這個參數用過.NET Core的童鞋都知道,這里我是直接拷貝該包的路由實現,如下:
文件上傳大小限制統一說明
我們知道無論是.NET還是.NET Core對于文件上傳大小都有默認限制大小,這里對.NET Core中文件大小各種環境配置做一個統一說明,如果你將.NET Core寄宿在IIS上運行,那么請修改web.config配置文件大小限制
<system.webServer><security><requestFiltering>//若不配置,默認是28.6兆<requestLimits?maxAllowedContentLength="1073741824"?/></requestFiltering></security> </system.webServer>如果在開發環境默認使用IIS運行應用程序,請通過如下根據實際情況配置文件上傳大小
services.Configure<IISServerOptions>(options?=>{options.MaxRequestBodySize?=?int.MaxValue;});如果程序運行在Kestrel服務器,那么請通過如下根據實際情況配置文件上傳大小
如果是通過表單上傳文件,那么請通過如下根據實際情況配置文件上傳大小
為了更好體驗可以再加上當前網絡寬帶情況或剩余多少分鐘,更詳細內容請參考:https://github.com/tusdotnet/tusdotnet?、https://github.com/tus/tus-js-client,關于大文件上傳處理到此結束,希望對那些苦苦尋找最終解決方案而無助的童鞋們提供最佳輪子,謝謝。
總結
以上是生活随笔為你收集整理的.NET或.NET Core Web APi基于tus协议实现断点续传的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于.NetCore3.1系列 —— 日
- 下一篇: asp.net ajax控件工具集 Au