diff --git a/src/CloudStoage.Domain/Etos/UploadingEto.cs b/src/CloudStoage.Domain/Etos/UploadingEto.cs index 48d6749574fa90817fa8427c295e718d9011152c..9aa05a3bdee32427037b649ca1c8c60fdfa59865 100644 --- a/src/CloudStoage.Domain/Etos/UploadingEto.cs +++ b/src/CloudStoage.Domain/Etos/UploadingEto.cs @@ -22,5 +22,5 @@ public class UploadingEto /// /// Stream /// - public Stream Stream { get; set; } + public string FilePath { get; set; } } diff --git a/src/CloudStoage.Domain/UploadingDto.cs b/src/CloudStoage.Domain/UploadingDto.cs index 1d5c52cc6f35f9f2d5b679c101c07f87fcae9504..82a8d4ddf7abe35a0cac0775c28f630b0a93a8e1 100644 --- a/src/CloudStoage.Domain/UploadingDto.cs +++ b/src/CloudStoage.Domain/UploadingDto.cs @@ -21,6 +21,10 @@ public class UploadingDto /// public long UploadingSize { get; set; } = 0; + /// + /// 上传速率(上一秒上传大小) + /// + public int Rate { get; set; } /// /// 上传状态 @@ -30,7 +34,7 @@ public class UploadingDto /// /// 上传进度 /// - public int Progress + public double Progress { get { @@ -39,7 +43,7 @@ public class UploadingDto return 0; } - return (int)((decimal)UploadingSize / (decimal)Length * 100m); + return Math.Round((double)(UploadingSize / (decimal)Length) * 100,2); } } } diff --git a/src/CloudStorage.Applications/CloudStorage.Applications.csproj b/src/CloudStorage.Applications/CloudStorage.Applications.csproj index 054a334fb6d08eb73ebe6d03d0838857ffc78fab..33b74c6c0db1c798892cd8ffef73eab1dece8e95 100644 --- a/src/CloudStorage.Applications/CloudStorage.Applications.csproj +++ b/src/CloudStorage.Applications/CloudStorage.Applications.csproj @@ -33,4 +33,8 @@ + + + + diff --git a/src/CloudStorage.Applications/EventHandle/UploadingEventBus.cs b/src/CloudStorage.Applications/EventHandle/UploadingEventBus.cs index e7203b8c7a0305143d3c18561fafb42905f8f704..4432e416a03bea2a3a7d48091e61e933aee4bd0f 100644 --- a/src/CloudStorage.Applications/EventHandle/UploadingEventBus.cs +++ b/src/CloudStorage.Applications/EventHandle/UploadingEventBus.cs @@ -4,9 +4,11 @@ using CloudStorage.Applications.Helpers; using CloudStorage.Domain.Shared; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System.Collections.Concurrent; +using System.Diagnostics; using System.Threading.Channels; using Token.EventBus; using Token.EventBus.Handlers; @@ -22,7 +24,7 @@ public class UploadingEventBus : ILocalEventHandler>, ISingle private readonly IKeyLocalEventBus DistributedEventBus; private readonly IConfiguration _configuration; private readonly TokenManage token; - + private bool succee = false; private HubConnection connection; public UploadingEventBus(IKeyLocalEventBus keyLocalEventBus, TokenManage token, IKeyLocalEventBus distributedEventBus, IConfiguration configuration) @@ -50,51 +52,100 @@ public class UploadingEventBus : ILocalEventHandler>, ISingle eventData.ForEach(x => { + var file = File.OpenRead(x.FilePath); UploadingList.Add(new UploadingDto { Id = x.Id, FileName = x.FileName, - Length = x.Length ?? 0, + Length = file.Length, Stats = UpdateStats.BeUploading }); + file.Close(); }); - int size = (1024 * 10); - foreach (var item in eventData) + // 接受服务器文件上传指令 + connection.On("file", (x) => { - int length = (int)(item.Length / size); - var channel = Channel.CreateBounded(length + 1); + succee = true; + }); - // 建立传输通道 - await connection.SendAsync("FileStreamSaveAsync", channel.Reader, JsonConvert.SerializeObject(new + int size = (1024 * 30); + foreach (var item in eventData) + { + FileStream fileStream = null; + try { - item.StorageId, - item.FileName, - item.Length - })); + fileStream = File.OpenRead(item.FilePath); - var bytesTransferred = 0; + item.Length = fileStream.Length; - // 定义下载缓存 - var b = new byte[size > item.Length ? item.Length ?? 0 : size]; - int len; - while ((len = await item.Stream.ReadAsync(b)) != 0) - { + int length = (int)(item.Length / size); + var channel = Channel.CreateBounded(length + 1); - await channel.Writer.WriteAsync(b); - bytesTransferred += len; - await UploadingSizeEvent(item.Id, bytesTransferred); - } + // 建立传输通道 + await connection.SendAsync("FileStreamSaveAsync", channel.Reader, JsonConvert.SerializeObject(new + { + item.StorageId, + item.FileName, + item.Length + })); + + var bytesTransferred = 0; - // 传输完成结束通道 - channel.Writer.Complete(); - await DistributedEventBus.PublishAsync("Storages", "上传文件成功"); + // 定义下载缓存 + var b = new byte[size > item.Length ? item.Length ?? 0 : size]; + int len; + var sw = Stopwatch.StartNew(); - await UploadingSizeEvent(item.Id, succeed: true); + // 保存上一次计算上传速率时间 + var now = DateTime.Now; + // 保存上次计算上传速率大小 + int rate = 0; + + while ((len = await fileStream.ReadAsync(b)) != 0) + { + await channel.Writer.WriteAsync(b); + await channel.Writer.WaitToWriteAsync(); + bytesTransferred += len; + for (int i = 0; i < 5; i++) + { + if (succee) + { + succee = false; + break; + } + else + { + await Task.Delay(1); + } + } + rate += len; + // 固定计算每秒上传速率 + if (DateTime.Now > now.AddSeconds(1)) + { + await UploadingSizeEvent(item.Id, bytesTransferred, rate); + rate = 0; + now = DateTime.Now; + } + } + + await UploadingSizeEvent(item.Id, bytesTransferred, rate); + sw.Stop(); + + // 传输完成结束通道 + channel.Writer.Complete(); + await DistributedEventBus.PublishAsync("Storages", "上传文件成功"); + + await UploadingSizeEvent(item.Id, succeed: true); + } + finally + { + fileStream?.Close(); + } } } - private async Task UploadingSizeEvent(Guid id, int BytesTransferred = 0, bool succeed = false) + private async Task UploadingSizeEvent(Guid id, int BytesTransferred = 0, int rate = 0, bool succeed = false) { foreach (var d in UploadingList) { @@ -103,10 +154,12 @@ public class UploadingEventBus : ILocalEventHandler>, ISingle if (succeed) { d.Stats = UpdateStats.Succeed; + d.Rate = rate; await KeyLocalEventBus.PublishAsync(KeyLoadNames.UploadingListName, d); return; } d.UploadingSize = BytesTransferred; + d.Rate = rate; await KeyLocalEventBus.PublishAsync(KeyLoadNames.UploadingListName, d); return; } diff --git a/src/CloudStorage.Applications/Helpers/CommonHelper.cs b/src/CloudStorage.Applications/Helpers/CommonHelper.cs index 6b1ef146d17a978bd95a4cabbc23a777e0204470..fb8c4bbed57620a9ff9bbf14c4e1cbc15314c53e 100644 --- a/src/CloudStorage.Applications/Helpers/CommonHelper.cs +++ b/src/CloudStorage.Applications/Helpers/CommonHelper.cs @@ -1,9 +1,24 @@ -using Token.Module.Dependencys; +using CloudStoage.Domain.Etos; +using Token.EventBus.EventBus; +using Token.Module.Dependencys; namespace CloudStorage.Applications.Helpers; public class CommonHelper : IScopedDependency { + + private readonly ILocalEventBus LocalEventBus; + + public CommonHelper(ILocalEventBus localEventBus) + { + LocalEventBus = localEventBus; + } + + /// + /// b转换格式 + /// + /// + /// public string GetFileSize(long? size) { if (size == null) @@ -14,12 +29,43 @@ public class CommonHelper : IScopedDependency if (size < num) return size + "B"; if (size < Math.Pow(num, 2)) - return ((long)size / num).ToString("f2") + "K"; //kb + return ((long)size / num).ToString("f2") + "KB"; //kb if (size < Math.Pow(num, 3)) - return ((long)size / Math.Pow(num, 2)).ToString("f2") + "M"; //M + return ((long)size / Math.Pow(num, 2)).ToString("f2") + "MB"; //M if (size < Math.Pow(num, 4)) - return ((long)size / Math.Pow(num, 3)).ToString("f2") + "G"; //G + return ((long)size / Math.Pow(num, 3)).ToString("f2") + "GB"; //G + + return ((long)size / Math.Pow(num, 4)).ToString("f2") + "TB"; //T + } + + public async Task PickAndShow(Guid? storageId) + { + PickOptions options = new() + { + PickerTitle = "请选择需要上传的文件", + }; + + try + { + var result = await FilePicker.Default.PickMultipleAsync(options); + if (result != null) + { + + var uploadings = result.Select(x => new UploadingEto + { + Id = Guid.NewGuid(), + FileName = x.FileName, + FilePath = x.FullPath, + StorageId = storageId, + }).ToList(); + + _ = LocalEventBus.PublishAsync(uploadings, false); + } + + } + catch (Exception ex) + { + } - return ((long)size / Math.Pow(num, 4)).ToString("f2") + "T"; //T } } diff --git a/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor b/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor index 45cf692c2577fd97e2ed666e5a6270927e68c2ec..161f0fe3f81f4f3c00289ae69edd8d9a375d3488 100644 --- a/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor +++ b/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor @@ -7,8 +7,12 @@ { +
+ @(CommonHelper.GetFileSize(d.UploadingSize)+"/"+CommonHelper.GetFileSize(d.Length)) + @(CommonHelper.GetFileSize(d.Rate) + "/s") +
- @(d.Progress)% + @(d.Progress)%
} diff --git a/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor.cs b/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor.cs index b4cd4acc9ad4accba5d4eb75664a9a5b37abc481..f5c5387a709816ce8d6af3b4a231fe66104fb416 100644 --- a/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor.cs +++ b/src/CloudStorage.Layou/Components/Uploads/UploadTheList.razor.cs @@ -1,5 +1,6 @@ using CloudStoage.Domain; using CloudStorage.Applications.EventHandle; +using CloudStorage.Applications.Helpers; using CloudStorage.Domain.Shared; using System.Collections.Concurrent; using System.Drawing; @@ -15,20 +16,24 @@ namespace CloudStorage.Layou.Components.Uploads [Inject] public IKeyLocalEventBus UploadTheListEventBus { get; set; } + [Inject] + public CommonHelper CommonHelper { get; set; } + public static BlockingCollection UploadingList { get; set; } protected override async void OnInitialized() { - UploadingList = UploadingEventBus.UploadingList; - - await UploadTheListEventBus.Subscribe(KeyLoadNames.UploadingListName, a => + await UploadTheListEventBus.Subscribe(KeyLoadNames.UploadingListName, a => { foreach (var d in UploadingList) { if (d.Id == a.Id) { - d.Stats = a.Stats; + if (d.Stats != a.Stats) + { + d.Stats = a.Stats; + } d.UploadingSize = a.UploadingSize; StateHasChanged(); return; diff --git a/src/CloudStorage.Layou/Pages/Storages.razor b/src/CloudStorage.Layou/Pages/Storages.razor index b7dada0eb29f02103e24cd16b1243887dea52478..e8d04c6741280e9d1ef69fff3edd9acb9d1a9710 100644 --- a/src/CloudStorage.Layou/Pages/Storages.razor +++ b/src/CloudStorage.Layou/Pages/Storages.razor @@ -67,8 +67,6 @@ -