diff options
Diffstat (limited to 'Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs')
| -rw-r--r-- | Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs | 195 |
1 files changed, 191 insertions, 4 deletions
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs index bcc39d11d..1f6641f3a 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; @@ -13,16 +14,97 @@ using Tango.FileSystem.Network; using Tango.FSE.Common.Connection; using Tango.FSE.Common.FileSystem; using Tango.Transport; +using Tango.Transport.Transporters; +using Tango.WebRTC; namespace Tango.FSE.UI.FileSystem { public class DefaultFileSystemProvider : ExtendedObject, IFileSystemProvider { private IMachineProvider _machineProvider; + private BasicTransporter _webRtcTransporter; + private const string WEB_RTC_CHANNEL_NAME = "FileSystemChannel"; + private const long MAX_CHUNK_SIZE = 1024 * 10; + private const long MAX_CHUNK_SIZE_WEB_RTC = 1024 * 15; + private List<FileSystemHandler> _activeHandlers; + + private bool _enableWebRTC; + public bool EnableWebRTC + { + get { return _enableWebRTC; } + set { _enableWebRTC = value; RaisePropertyChangedAuto(); } + } + + private bool _isWebRtcAvailable; + public bool IsWebRtcAvailable + { + get { return _isWebRtcAvailable; } + private set { _isWebRtcAvailable = value; RaisePropertyChangedAuto(); } + } public DefaultFileSystemProvider(IMachineProvider machineProvider) { + _activeHandlers = new List<FileSystemHandler>(); + + EnableWebRTC = true; //TODO: From Settings.. _machineProvider = machineProvider; + _machineProvider.MachineConnected += _machineProvider_MachineConnected; + _machineProvider.MachineDisconnected += _machineProvider_MachineDisconnected; + } + + private void _machineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e) + { + IsWebRtcAvailable = false; + + foreach (var handler in _activeHandlers.ToList()) + { + try + { + handler.RaiseFailed(new TransporterDisconnectedException("Machine disconnected.")); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + + _activeHandlers.Clear(); + } + + private async void _machineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + if (EnableWebRTC) + { + try + { + IsWebRtcAvailable = false; + + await _machineProvider.MachineOperator.SendGenericRequest<InitWebRtcRequest, InitWebRtcResponse>(new InitWebRtcRequest() + { + DataChannelName = WEB_RTC_CHANNEL_NAME + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(60), + Priority = QueuePriority.Low + }); + + _webRtcTransporter = new BasicTransporter(new WebRtcTransportAdapter(_machineProvider.MachineOperator, WebRtcTransportAdapterMode.Active, WEB_RTC_CHANNEL_NAME)); + _webRtcTransporter.UseKeepAlive = false; + _webRtcTransporter.ComponentName = "File System Active WebRTC Transporter"; + await _webRtcTransporter.Connect(); + + IsWebRtcAvailable = true; + + LogManager.Log("FileSystem via WebRTC is ready."); + } + catch (Exception ex) + { + IsWebRtcAvailable = false; + EnableWebRTC = false; + + LogManager.Log(ex, "Error initializing FileSystem via WebRTC."); + } + } } public async Task<IFileSystemContainer> GetFolder(string path) @@ -100,6 +182,8 @@ namespace Tango.FSE.UI.FileSystem } }); + _activeHandlers.Add(handler); + ThreadFactory.StartNew(async () => { try @@ -135,11 +219,13 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + _activeHandlers.Remove(handler); handler.RaiseFailed(ex); return; } long position = 0; + bool webRtcFailed = false; var tempFile = TemporaryManager.CreateFile(); @@ -153,13 +239,32 @@ namespace Tango.FSE.UI.FileSystem try { - var response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>( - new ChunkDownloadRequest() + ChunkDownloadResponse response = null; + ChunkDownloadRequest request = new ChunkDownloadRequest() { - MaxChunkSize = 1024 * 10, + MaxChunkSize = MAX_CHUNK_SIZE, OperationId = operationId, Position = position, - }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low }); + }; + + if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed) + { + try + { + request.MaxChunkSize = MAX_CHUNK_SIZE_WEB_RTC; + response = await _webRtcTransporter.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low }); + } + catch (Exception ex) + { + webRtcFailed = true; + LogManager.Log(ex, "WebRTC chunk download failed. Falling back to standard download..."); + continue; + } + } + else + { + response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low }); + } using (FileStream fs = new FileStream(tempFile, FileMode.Append)) { @@ -171,6 +276,7 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + _activeHandlers.Remove(handler); tempFile.Delete(); handler.RaiseFailed(ex); return; @@ -203,6 +309,8 @@ namespace Tango.FSE.UI.FileSystem { tempFile.Delete(); } + + _activeHandlers.Remove(handler); }); return Task.FromResult(handler); @@ -212,5 +320,84 @@ namespace Tango.FSE.UI.FileSystem { throw new NotImplementedException(); } + + public async Task Copy(FileSystemItem source, FileSystemItem target) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (target.Type == FileSystemItemType.File) + { + throw new NotSupportedException("The target file system item is not a valid container."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<CopyRequest, CopyResponse>(new CopyRequest() + { + + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) + + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + + public async Task Move(FileSystemItem source, FileSystemItem target) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (target.Type == FileSystemItemType.File) + { + throw new NotSupportedException("The target file system item is not a valid container."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() + { + + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) + + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + + public async Task Rename(FileSystemItem source, string newName) + { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for copying."); + } + if (newName.ToList().Exists(x => Path.GetInvalidFileNameChars().Contains(x))) + { + throw new ArgumentException("The new name contains invalid characters."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() + { + + Source = source.Path, + Destination = Path.Combine(Path.GetDirectoryName(source.Path), newName) + + }); + } + + public async Task Delete(FileSystemItem item) + { + if (item.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for deletion."); + } + + await _machineProvider.MachineOperator.SendGenericRequest<DeleteRequest, DeleteResponse>(new DeleteRequest() + { + Path = item.Path + }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(120) }); + } } } |
