public override async Task StartAsync(ManagedTaskProgress progress, CancellationToken cancellationToken = default) { progress.Report(50, 1, "Running data extract..."); var downloadStream = await _downloadData.GetStream(cancellationToken); var filename = downloadStream.FileName; var stream = downloadStream.Stream; progress.Report(100, 2, "Download ready..."); await _sharedSettings.StartDataStream(_reference, stream, _downloadUrl, "file", filename, false, cancellationToken); var url = $"{_downloadUrl.Url}/download/{_reference}"; var downloadMessage = new DownloadReadyMessage() { InstanceId = _sharedSettings.InstanceId, SecurityToken = _sharedSettings.SecurityToken, ConnectionId = _connectionId, Reference = _reference, HubKey = _hubKey, Url = url }; var returnValue = await _sharedSettings.PostAsync <DownloadReadyMessage, ReturnValue>("Remote/DownloadReady", downloadMessage, cancellationToken); if (!returnValue.Success) { throw new RemoteOperationException($"The data download did not completed. {returnValue.Message}", returnValue.Exception); } }
public override async Task StartAsync(ManagedTaskProgress progress, CancellationToken cancellationToken = default) { progress.Report(50, 1, "Preparing files..."); var downloadStream = await _connectionFlatFile.DownloadFiles(_flatFile, _path, _files, _files.Length > 1, cancellationToken); var filename = _files.Length == 1 ? _files[0] : _flatFile.Name + "_files.zip"; progress.Report(100, 2, "Files ready for download..."); await _sharedSettings.StartDataStream(_messageId, downloadStream, _downloadUrl, "file", filename, false, cancellationToken); var url = $"{_sharedSettings.RemoteSettings.Network.ProxyUrl}/download/{_messageId}"; var downloadMessage = new DownloadReadyMessage() { InstanceId = _sharedSettings.InstanceId, SecurityToken = _sharedSettings.SecurityToken, ConnectionId = _connectionId, Reference = _reference, HubKey = _hubKey, Url = url }; var returnValue = await _sharedSettings.PostAsync <DownloadReadyMessage, ReturnValue>("Remote/DownloadReady", downloadMessage, cancellationToken); if (!returnValue.Success) { throw new RemoteOperationException($"The file download did not completed. {returnValue.Message}", returnValue.Exception); } }
/// <summary> /// Processes a message from the webserver, and redirects to the appropriate method. /// </summary> /// <param name="remoteMessage"></param> /// <returns></returns> private async Task ProcessMessage(RemoteMessage remoteMessage) { var cancellationTokenSource = new CancellationTokenSource(); var commandCancel = cancellationTokenSource.Token; try { // var remoteMessage = Json.DeserializeObject<RemoteMessage>(message, TemporaryEncryptionKey); //if the success is false, then it is a dummy message returned through a long polling timeout, so just ignore. if (!remoteMessage.Success) { return; } _logger.LogDebug($"Message received is command: {remoteMessage.Method}, messageId: {remoteMessage.MessageId}."); //JObject values = (JObject)command.Value; // if (!string.IsNullOrEmpty((string)command.Value)) // values = JObject.Parse((string)command.Value); var method = typeof(RemoteOperations).GetMethod(remoteMessage.Method); if (method == null) { _logger.LogError(100, "Unknown method : " + remoteMessage.Method); var error = new ReturnValue <object>(false, $"Unknown method: {remoteMessage.Method}.", null); AddResponseMessage(remoteMessage.MessageId, error); return; } if (remoteMessage.SecurityToken == _sharedSettings.SecurityToken) { Stream stream; // if method is a task, execute async if (method.ReturnType == typeof(Task)) { var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }); if (task.IsFaulted) { throw task.Exception; } await task.ConfigureAwait(false); return; // if method is a void, execute sync } else if (method.ReturnType == typeof(void)) { method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }); return; } // if method is a task with a return type, create a call back stream to execute else if (method.ReturnType.BaseType == typeof(Task)) { var args = method.ReturnType.GetGenericArguments(); if (args.Length > 0 && args[0].IsAssignableFrom(typeof(Stream))) { var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }); if (task.IsFaulted) { throw task.Exception; } await task.ConfigureAwait(false); var resultProperty = task.GetType().GetProperty("Result"); stream = (Stream)resultProperty.GetValue(task); } else { stream = new StreamAsyncAction <object>(async() => { var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }); if (task.IsFaulted) { throw task.Exception; } await task.ConfigureAwait(false); var property = task.GetType().GetProperty("Result"); if (property == null) { throw new RemoteOperationException($"The method {method.Name} does not return a result."); } return(property.GetValue(task)); }); } // if method is a stream, then start the stream. } else if (method.ReturnType.IsAssignableFrom(typeof(Stream))) { try { stream = (Stream)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }); } catch (TargetInvocationException ex) { throw ex.InnerException ?? ex; } } // other return types, execute sync. else { try { stream = new StreamAction <object>(() => method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel })); } catch (TargetInvocationException ex) { throw ex.InnerException ?? ex; } } await _sharedSettings.StartDataStream(remoteMessage.MessageId, stream, remoteMessage.DownloadUrl, "json", "", false, commandCancel); } else { throw new RemoteException($"The command {remoteMessage.Method} failed due to mismatching security tokens."); } } catch (Exception ex) { _logger.LogError(100, ex, "Unknown error processing incoming message: " + ex.Message); var error = new ReturnValue <object>(false, $"{ex.Message}", ex); // when error occurs, set local cache or send to proxy so message gets to client. if (remoteMessage.DownloadUrl.DownloadUrlType != EDownloadUrlType.Proxy) { var stream = new StreamAction <ReturnValue>(() => error); await _sharedSettings.StartDataStream(remoteMessage.MessageId, stream, remoteMessage.DownloadUrl, "json", "", true, commandCancel); // // _memoryCache.Set(remoteMessage.MessageId, stream, TimeSpan.FromSeconds(5)); } else { var result = new ReturnValue(false, ex.Message, ex); await _sharedSettings.PostDirect($"{remoteMessage.DownloadUrl.Url}/error/{remoteMessage.MessageId}", result.Serialize(), commandCancel); } } }