using System; using System.Threading; using ZeroLevel.Models; namespace ZeroLevel.Network.FileTransfer { public sealed class FileClient : BaseFileTransfer, IFileClient { private readonly ExClient _client; private readonly string _baseFolder; private readonly ClientFolderNameMapper _nameMapper; private readonly bool _disposeClient; internal FileClient(ExClient client, string baseFolder, ClientFolderNameMapper nameMapper, bool disposeClient) : base(baseFolder) { _client = client ?? throw new Exception(nameof(client)); _baseFolder = baseFolder ?? throw new Exception(nameof(baseFolder)); _nameMapper = nameMapper ?? throw new Exception(nameof(nameMapper)); _disposeClient = disposeClient; _client.Router.RegisterInbox("__upload_file_start", (c, f) => Receiver.Incoming(f, nameMapper(c))); _client.Router.RegisterInbox("__upload_file_frame", (c, f) => Receiver.Incoming(f)); _client.Router.RegisterInbox("__upload_file_complete", (c, f) => Receiver.Incoming(f)); } public void Dispose() { if (_disposeClient) { _client?.Dispose(); } } public void Send(string fileName, Action completeHandler = null, Action errorHandler = null) { PushTransferTask(fileName, completeHandler, errorHandler); } internal override void ExecuteSendFile(FileReader reader, FileTransferTask task) { Log.Info($"Start upload file {reader.Path}"); var startinfo = reader.GetStartInfo(); using (var signal = new ManualResetEvent(false)) { bool next = false; if (false == _client.Request("__upload_file_start", startinfo, r => { next = r.Success; signal.Set(); }).Success) { next = false; signal.Set(); } signal.WaitOne(5000); if (next) { foreach (var chunk in reader.Read()) { signal.Reset(); if (_client.Request("__upload_file_frame", chunk, r => { next = r.Success; signal.Set(); }).Success == false) { next = false; signal.Set(); } signal.WaitOne(); if (!next) { break; } } } if (next) { _client.Request("__upload_file_complete", reader.GetCompleteInfo(), r => { if (r.Success == false) { Log.Warning($"Unsuccess send file. {r.Comment}"); } }); } } Log.Debug($"Stop upload file {reader.Path}"); } } }