/// <summary> /// Connect to server. This opens a persistent connection allowing multiple remote calls /// until <see cref="Disconnect(bool)" /> is called. /// </summary> /// <param name="keepAlive">Whether to send pings over the connection to keep it alive</param> /// <returns>True if succeeded, false if not</returns> public virtual bool Connect(bool keepAlive = true) { var source = new NamedPipeClientStream( ".", PipeName, PipeDirection.InOut, PipeOptions.Asynchronous); try { source.Connect(500); } catch (TimeoutException) { return(false); } Stream = new IpcStream(source, KnownTypes); if (keepAlive) { StartPing(); } return(true); }
/// <summary> /// Register a service interface on the server /// </summary> /// <param name="t">The interface of the service</param> /// <param name="instance">Instance of a class implementing the service</param> public void RegisterService(Type t, object instance) { services[t.Name] = instance; types[t.Name] = t; IpcStream.ScanInterfaceForTypes(t, KnownTypes); }
/// <summary> /// Register a service interface on the server /// </summary> /// <typeparam name="T">The interface of the service</typeparam> /// <param name="instance">Instance of a class implementing the service</param> public void RegisterService <T>(T instance) { if (!(instance is T)) { throw new InvalidOperationException("Instance must implement service interface"); } services[typeof(T).Name] = instance; types[typeof(T).Name] = typeof(T); IpcStream.ScanInterfaceForTypes(typeof(T), KnownTypes); }
/// <summary> /// Scans the service interface and builds proxy class /// </summary> /// <typeparam name="T">Service interface, must equal server-side</typeparam> /// <returns>Proxy class for remote calls</returns> public T GetServiceProxy <T>() { IpcStream.ScanInterfaceForTypes(typeof(T), KnownTypes); return((T)_proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(T), new Proxy <T>(this))); }
/// <summary> /// Process a received message by calling the corresponding method on the service instance and /// returning the return value over the network. /// </summary> /// <param name="source">Network stream</param> private bool ProcessMessage(NamedPipeServerStream source) { // Checks, if the stream is from an allowed client ... if (!CheckPipeServerStreamForAllowedProcess(source)) { return(false); } var stream = new IpcStream(source, KnownTypes); var msg = stream.ReadMessage(); // this was a close-connection notification if (msg == null || msg.StatusMsg == StatusMessage.CloseConnection) { return(false); } if (msg.StatusMsg == StatusMessage.Ping) { return(true); } var processedOk = false; var error = ""; object rv = null; // find the service if (services.TryGetValue(msg.Service, out var instance) && instance != null) { // get the method var method = instance.GetType().GetMethod(msg.Method); // double check method existence against type-list for security // typelist will contain interfaces instead of instances if (GetServiceMethod(types[msg.Service], msg.Method) != null && method != null) { try { // invoke method rv = method.Invoke(instance, msg.Parameters); processedOk = true; } catch (Exception e) { error = e.ToString(); } } else { error = "Could not find method"; } } else { error = "Could not find service"; } // return either return value or error message var returnMsg = processedOk ? new IpcMessage { Return = rv } : new IpcMessage { Error = error }; stream.WriteMessage(returnMsg); // if there's more to come, keep reading a next message return(msg.StatusMsg == StatusMessage.KeepAlive); }