ClientProvider.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System.Collections.Concurrent;
  2. using System.Diagnostics;
  3. using Universal;
  4. namespace EEMSClientCore;
  5. public class ClientProvider(IClientCaller clientCaller, IClientBaseProvider baseProvider) : IClientProvider
  6. {
  7. private static readonly ConcurrentDictionary<FileType, MemoryStream> _streamBuffer = [];
  8. public static readonly ConcurrentDictionary<FileType, string> _savePath = [];
  9. //Receive Files from Server
  10. public Task<bool> PushFile(Guid guid, FileType fileType, byte[] buffer, int current, int total)
  11. {
  12. if (baseProvider is null)
  13. return Task.FromResult(false);
  14. if (!_streamBuffer.TryGetValue(fileType, out MemoryStream? stream) || stream is null)
  15. {
  16. if (current != 1)
  17. return Task.FromResult(false);
  18. if (!baseProvider.AllowReceiveFile())
  19. return Task.FromResult(false);
  20. baseProvider.StartFileReceiveNotify(fileType);
  21. stream = new();
  22. _streamBuffer[fileType] = stream;
  23. Timer timer = new(FileCleanerTimerCallback, fileType, 600000, Timeout.Infinite);
  24. }
  25. stream.Write(buffer);
  26. if (current != total)
  27. return Task.FromResult(true);
  28. string? tempPath = fileType switch
  29. {
  30. FileType.Recipe => baseProvider.RecipePath,
  31. FileType.Config => baseProvider.ConfigPath,
  32. _ => "Undefined"
  33. };
  34. tempPath ??= "Undefined";
  35. string path = Path.Combine(tempPath, "Receive");
  36. if (!Compressor.DecompressZipFile(new(path), stream))
  37. return Task.FromResult(false);
  38. if (_streamBuffer.TryRemove(fileType, out MemoryStream? memoryStream) && memoryStream is not null)
  39. memoryStream.Dispose();
  40. baseProvider?.FileReceivedNotify(fileType, path);
  41. return Task.FromResult(true);
  42. }
  43. public Task<bool> RequestFile(Guid guid, FileType fileType)
  44. {
  45. Debug.WriteLine($"RequestFile {guid} {fileType}");
  46. string? filePath = fileType switch
  47. {
  48. FileType.Config => baseProvider.ConfigPath,
  49. FileType.Recipe => baseProvider.RecipePath,
  50. _ => default
  51. };
  52. if (string.IsNullOrEmpty(filePath))
  53. return Task.FromResult(false);
  54. if (!Directory.Exists(filePath))
  55. return Task.FromResult(false);
  56. using MemoryStream stream = new();
  57. Compressor.CompressZipFileDirectory(new(filePath), stream);
  58. return SendFile(guid, stream);
  59. }
  60. private async Task<bool> SendFile(Guid guid, MemoryStream stream)
  61. {
  62. if (!stream.Split(out List<byte[]>? buffer, 8192) || buffer is null)
  63. return false;
  64. for (int i = 0; i < buffer.Count; i++)
  65. {
  66. try
  67. {
  68. if (!await clientCaller.FilePack(guid, buffer[i], i + 1, buffer.Count))
  69. return false;
  70. }
  71. catch
  72. {
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. private void FileCleanerTimerCallback(object? state)
  79. {
  80. if (state is not FileType fileType)
  81. return;
  82. if (_streamBuffer.TryRemove(fileType, out MemoryStream? memoryStream) && memoryStream is not null)
  83. memoryStream.Dispose();
  84. }
  85. }
  86. public interface IClientBaseProvider
  87. {
  88. string? RecipePath { get; set; }
  89. string? ConfigPath { get; set; }
  90. bool AllowReceiveFile();
  91. void FileReceivedNotify(FileType fileType, string path);
  92. void StartFileReceiveNotify(FileType fileType);
  93. }