public void ServerResponds() { using (var container = SetupMefContainer()) { using (var server = container.GetExport <IServerProcessProxy>().Value) { var waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); var request = new IpcRequest { RequestId = 5, Protocol = IpcProtocols.Echo, Data = new IpcStringData { Text = "sdfsdsd" } }; IpcResponse response = null; server.RunAsync(request, x => { response = x; waitHandle.Set(); }); Assert.IsTrue(waitHandle.WaitOne(TimeSpan.FromSeconds(5.0)), "Server did not respond within 5 seconds."); Assert.AreEqual(5, response.RequestId); Assert.AreEqual(IpcProtocols.Echo, response.Protocol); Assert.IsNotNull(request.Data); Assert.IsNotNull(response.Data); Assert.AreEqual(request.Data.GetType(), typeof(IpcStringData)); Assert.AreEqual(response.Data.GetType(), typeof(IpcStringData)); Assert.AreEqual((request.Data as IpcStringData).Text, (response.Data as IpcStringData).Text); } } }
public void Enqueue(IpcResponse response) { lock (_lock) { _responses.Enqueue(response); } _waitHandle.Set(); }
private static string GetErrorResponse(string pipeName, Exception ex) { var response = new IpcResponse(false); response.SetData($"{pipeName} named pipe: command handling error. {ex.Message}"); return(JsonConvert.SerializeObject(response)); }
protected void SendResponse(IpcResponse response) { var formatter = (IFormatter) new BinaryFormatter(); formatter.Serialize(_namedPipeServer, response); _namedPipeServer.WaitForPipeDrain(); }
protected virtual void OnResponseReceived(IpcResponse obj) { var handler = ResponseReceived; if (handler != null) { handler(obj); } }
/// <exception cref="IpcSerializationException">If unable to serialize request</exception> /// <exception cref="IpcCommunicationException">If communication is broken</exception> /// <exception cref="IpcFaultException">If error occurred in server</exception> public async Task InvokeAsync(Expression <Func <TInterface, Task> > exp, CancellationToken cancellationToken = default) { IpcRequest request = GetRequest(exp, new MyInterceptor <Task>()); IpcResponse response = await GetResponseAsync(request, cancellationToken).ConfigureAwait(false); if (!response.Succeed()) { throw response.CreateFaultException(); } }
/// <exception cref="IpcSerializationException">If unable to serialize request</exception> /// <exception cref="IpcCommunicationException">If communication is broken</exception> /// <exception cref="IpcFaultException">If error occurred in server</exception> public async Task InvokeAsync(Expression <Action <TInterface> > exp, CancellationToken cancellationToken = default) { IpcRequest request = GetRequest(exp, DispatchProxy.Create <TInterface, IpcProxy>()); IpcResponse response = await GetResponseAsync(request, cancellationToken).ConfigureAwait(false); if (!response.Succeed()) { throw response.CreateFaultException(); } }
private void DisplayTreeStats(IProtoBufSerializer serializer, GetFileSystemResponse response, bool verbose) { Trace.WriteLine("====================================================================="); Trace.WriteLine("FileSystem tree stats:"); { var mem = new MemoryStream(); var sw = new Stopwatch(); var ipcResponse = new IpcResponse { RequestId = 0, Protocol = IpcProtocols.TypedMessage, Data = response }; sw.Start(); serializer.Serialize(mem, ipcResponse); sw.Stop(); Trace.WriteLine(string.Format("ProtoBuf request of {0:n0} bytes serialized in {1} msec.", mem.Length, sw.ElapsedMilliseconds)); } var stats = new TreeStats(); stats.ProcessTree(null, "", response.Tree.Root); Trace.WriteLine(string.Format("Directory count: {0:n0}", stats.DirectoryCount)); Trace.WriteLine(string.Format("File count: {0:n0}", stats.FileCount)); Trace.WriteLine(string.Format("Total File size: {0:n0} bytes", stats.TotalSize)); if (verbose) { Trace.WriteLine("====================================================================="); Trace.WriteLine(" Files sorted by count"); foreach (var item in stats.Extensions.OrderByDescending(x => x.Value.FileCount)) { Trace.WriteLine(string.Format("Extension \"{0}\": {1:n0} files, {2:n0} bytes", item.Key.ToUpperInvariant(), item.Value.FileCount, item.Value.TotalSize)); } Trace.WriteLine("====================================================================="); Trace.WriteLine(" Files sorted by total length"); foreach (var item in stats.Extensions.OrderByDescending(x => x.Value.TotalSize)) { Trace.WriteLine(string.Format("Extension \"{0}\": {2:n0} bytes, {1:n0} files", item.Key.ToUpperInvariant(), item.Value.FileCount, item.Value.TotalSize)); } OutputDirectorytree(0, "", stats.RootDirectory); } }
/// <exception cref="IpcSerializationException">If unable to serialize request</exception> /// <exception cref="IpcCommunicationException">If communication is broken</exception> /// <exception cref="IpcFaultException">If error occurred in server</exception> public async Task <TResult> InvokeAsync <TResult>(Expression <Func <TInterface, TResult> > exp, CancellationToken cancellationToken = default) { IpcRequest request = GetRequest(exp, new MyInterceptor <TResult>()); IpcResponse response = await GetResponseAsync(request, cancellationToken).ConfigureAwait(false); if (!response.Succeed()) { throw response.CreateFaultException(); } if (!_options.ValueConverter.TryConvert(response.Data, typeof(TResult), out object @return)) { throw new IpcSerializationException($"Unable to convert returned value to '{typeof(TResult).Name}'."); } return((TResult)@return); }
public IpcResponse SendMessage(Message message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } IpcResponse ipcResponse = null; using (var notifier = new ManualResetEventSlim(false)) { var eventHandler = new EventHandler <MessageReceivedEventArgs>( delegate(object sender, MessageReceivedEventArgs args) { if (args.Message.Type != MessageType.Response) { return; } var resp = (IpcResponse)args.Message.Payload; if (resp.RequestId != message.Id) { return; } ipcResponse = resp; notifier.Set(); }); try { message.SenderInfo = _configuration.ClientInfo; _messageChannel.MessageReceived += eventHandler; _messageChannel.Broadcast(message); notifier.Wait(); } finally { _messageChannel.MessageReceived -= eventHandler; } } return(ipcResponse); }
public void Write(IpcResponse response) { byte[] binary = _serializer.SerializeResponse(response); WriteMessage(binary); }
private async Task ProcessAsync(Stream server, CancellationToken stoppingToken) { if (stoppingToken.IsCancellationRequested) { return; } if (_options.StreamTranslator != null) { server = _options.StreamTranslator(server); } using (var writer = new IpcWriter(server, _options.Serializer, leaveOpen: true)) using (var reader = new IpcReader(server, _options.Serializer, leaveOpen: true)) using (IDisposable loggingScope = _logger.BeginScope(new Dictionary <string, object> { { "threadId", Thread.CurrentThread.ManagedThreadId } })) { try { IpcRequest request; try { _logger.LogDebug($"Client connected, reading request..."); request = await reader.ReadIpcRequestAsync(stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.BadRequest, "Failed to deserialize request.", ex); } stoppingToken.ThrowIfCancellationRequested(); IpcResponse response; try { _logger.LogDebug($"Request received, invoking '{request.MethodName}'..."); using (IServiceScope scope = _serviceProvider.CreateScope()) { response = await GetReponseAsync(request, scope).ConfigureAwait(false); } } catch (Exception ex) when(!(ex is IpcException)) { throw new IpcFaultException(IpcStatus.InternalServerError, "Unexpected exception raised from user code", ex); } stoppingToken.ThrowIfCancellationRequested(); try { _logger.LogDebug($"Sending response..."); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.InternalServerError, "Failed to serialize response.", ex); } _logger.LogDebug($"Process finished."); } catch (IpcCommunicationException ex) { _logger.LogError(ex, "Communication error occurred."); // if communication error occurred, client will probably not receive any response } catch (OperationCanceledException ex) { _logger.LogWarning(ex, "IPC request process cancelled"); IpcResponse response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError("IPC request process cancelled") : IpcResponse.InternalServerError(); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcFaultException ex) { _logger.LogError(ex, "Failed to process IPC request."); IpcResponse response; switch (ex.Status) { case IpcStatus.BadRequest: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.BadRequest(ex.Message, ex.InnerException) : IpcResponse.BadRequest(); break; default: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError(ex.Message, ex.InnerException) : IpcResponse.InternalServerError(); break; } await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } } }
private async Task <IpcResponse> GetReponseAsync(IpcRequest request, IServiceScope scope) { object service = scope.ServiceProvider.GetService <TContract>(); if (service == null) { throw new IpcFaultException(IpcStatus.BadRequest, $"No implementation of interface '{typeof(TContract).FullName}' found."); } MethodInfo method = GetUnambiguousMethod(request, service); if (method == null) { throw new IpcFaultException(IpcStatus.BadRequest, $"Method '{request.MethodName}' not found in interface '{typeof(TContract).FullName}'."); } ParameterInfo[] paramInfos = method.GetParameters(); object[] requestParameters = request.Parameters?.ToArray() ?? Array.Empty <object>(); if (paramInfos.Length != requestParameters.Length) { throw new IpcFaultException(IpcStatus.BadRequest, $"Method '{request.MethodName}' expects {paramInfos.Length} parameters."); } Type[] genericArguments = method.GetGenericArguments(); Type[] requestGenericArguments = request.GenericArguments?.ToArray() ?? Array.Empty <Type>(); if (genericArguments.Length != requestGenericArguments.Length) { throw new IpcFaultException(IpcStatus.BadRequest, $"Generic arguments mismatch."); } object[] args = new object[paramInfos.Length]; for (int i = 0; i < args.Length; i++) { object origValue = requestParameters[i]; Type destType = paramInfos[i].ParameterType; if (destType.IsGenericParameter) { destType = requestGenericArguments[destType.GenericParameterPosition]; } if (_options.ValueConverter.TryConvert(origValue, destType, out object arg)) { args[i] = arg; } else { throw new IpcFaultException(IpcStatus.BadRequest, $"Cannot convert value of parameter '{paramInfos[i].Name}' ({origValue}) from {origValue.GetType().Name} to {destType.Name}."); } } if (method.IsGenericMethod) { method = method.MakeGenericMethod(requestGenericArguments); } object @return = method.Invoke(service, args); if (@return is Task task) { await task.ConfigureAwait(false); PropertyInfo resultProperty = @return.GetType().GetProperty("Result"); return(IpcResponse.Success(resultProperty?.GetValue(@return))); } else { return(IpcResponse.Success(@return)); } }
public void WriteResponse(IpcResponse response) { WriteMessage(response); }
protected virtual void OnResponseReceived(IpcResponse obj) { ResponseReceived?.Invoke(obj); }
private void DisplayTreeStats(IProtoBufSerializer serializer, GetFileSystemResponse response, bool verbose) { Trace.WriteLine("====================================================================="); Trace.WriteLine("FileSystem tree stats:"); { var mem = new MemoryStream(); var sw = new Stopwatch(); var ipcResponse = new IpcResponse { RequestId = 0, Protocol = IpcProtocols.TypedMessage, Data = response }; sw.Start(); serializer.Serialize(mem, ipcResponse); sw.Stop(); Trace.WriteLine(string.Format("ProtoBuf request of {0:n0} bytes serialized in {1} msec.", mem.Length, sw.ElapsedMilliseconds)); } var stats = new TreeStats(); stats.ProcessTree(null, "", response.Tree.Root); Trace.WriteLine(string.Format("Directory count: {0:n0}", stats.DirectoryCount)); Trace.WriteLine(string.Format("File count: {0:n0}", stats.FileCount)); Trace.WriteLine(string.Format("Total File size: {0:n0} bytes", stats.TotalSize)); if (verbose) { Trace.WriteLine("====================================================================="); Trace.WriteLine(" Files sorted by count"); foreach (var item in stats.Extensions.OrderByDescending(x => x.Value.FileCount)) { Trace.WriteLine(string.Format("Extension \"{0}\": {1:n0} files, {2:n0} bytes", item.Key.ToUpperInvariant(), item.Value.FileCount, item.Value.TotalSize)); } Trace.WriteLine("====================================================================="); Trace.WriteLine(" Files sorted by total length"); foreach (var item in stats.Extensions.OrderByDescending(x => x.Value.TotalSize)) { Trace.WriteLine(string.Format("Extension \"{0}\": {2:n0} bytes, {1:n0} files", item.Key.ToUpperInvariant(), item.Value.FileCount, item.Value.TotalSize)); } OutputDirectorytree(0, "", stats.RootDirectory); } }
public byte[] SerializeResponse(IpcResponse response) { return Serialize(response); }
private async Task ProcessAsync(Stream server, string clientIdentifier, CancellationToken stoppingToken) { if (stoppingToken.IsCancellationRequested) { return; } if (_options.StreamTranslator != null) { server = _options.StreamTranslator(server); } using (var writer = new IpcWriter(server, _options.Serializer, leaveOpen: true)) using (var reader = new IpcReader(server, _options.Serializer, leaveOpen: true)) using (IDisposable loggingScope = _logger.BeginScope(new Dictionary <string, object> { { "threadId", Thread.CurrentThread.ManagedThreadId } })) { try { IpcRequest request; try { // Log first connection if loglevel >= information. // Log every connection if loglevel <= debug. string message = $"Client connected from {clientIdentifier}."; if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug(message); } else if (!_knownConections.ContainsKey(clientIdentifier)) { Logger.LogInformation(message); _knownConections[clientIdentifier] = true; } request = await reader.ReadIpcRequestAsync(stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.BadRequest, "Failed to deserialize request.", ex); } stoppingToken.ThrowIfCancellationRequested(); IpcResponse response; try { string parameters = (request.Parameters == null) ? "None" : string.Join(",", request.Parameters); var paramTypes = (request.ParameterTypesByName == null) ? ((request.ParameterTypes == null) ? "None" : string.Join(", ", request.ParameterTypes)) : string.Join(", ", request.ParameterTypesByName.Select(x => x.ParameterType)); _logger.LogDebug($"Request received, invoking '{request.MethodName}' Params '{parameters}' Types '{paramTypes}'..."); using (IServiceScope scope = _serviceProvider.CreateScope()) { response = await GetReponseAsync(request, scope).ConfigureAwait(false); } } catch (Exception ex) when(!(ex is IpcException)) { throw new IpcFaultException(IpcStatus.InternalServerError, "Unexpected exception raised from user code", ex); } stoppingToken.ThrowIfCancellationRequested(); try { _logger.LogTrace($"Sending response for '{request.MethodName}'..."); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.InternalServerError, "Failed to serialize response.", ex); } _logger.LogTrace($"Process finished for '{request.MethodName}'."); } catch (IpcCommunicationException ex) { _logger.LogError(ex, "Communication error occurred."); // if communication error occurred, client will probably not receive any response } catch (OperationCanceledException ex) { _logger.LogWarning(ex, "IPC request process cancelled"); IpcResponse response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError("IPC request process cancelled") : IpcResponse.InternalServerError(); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcFaultException ex) { if (ex.Status != IpcStatus.InternalServerError || _options.LogInternalServerErrors) { _logger.LogError(ex, "Failed to process IPC request."); } IpcResponse response; switch (ex.Status) { case IpcStatus.BadRequest: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.BadRequest(ex.Message, ex.InnerException) : IpcResponse.BadRequest(); break; default: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError(ex.Message, ex.InnerException) : IpcResponse.InternalServerError(); break; } await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } } }
public void Enqueue(IpcResponse response) { lock (_lock) { _responses.Enqueue(response); } _waitHandle.Set(); }
protected virtual void OnResponseReceived(IpcResponse obj) { var handler = ResponseReceived; if (handler != null) handler(obj); }
public async Task WriteAsync(IpcResponse response, CancellationToken cancellationToken = default) { byte[] binary = _serializer.SerializeResponse(response); await WriteMessageAsync(binary, cancellationToken).ConfigureAwait(false); }