Exemplo n.º 1
0
        /// <summary>
        /// Write a <see cref="IpcMessage"/> to the network
        /// </summary>
        /// <param name="msg">Message to write</param>
        public void WriteMessage(IpcMessage msg)
        {
            // serialize
            DataContractSerializer serializer = new DataContractSerializer(typeof(IpcMessage), KnownTypes);

            using (MemoryStream stream = new MemoryStream())
            {
                XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream);

                serializer.WriteObject(writer, msg);
                writer.Flush();

                byte[] binaryMsg = stream.ToArray();

                // encrypt message
                if (encrypted)
                {
                    if (Encryptor == null)
                    {
                        throw new NullReferenceException("Encryption requested while no encryptor was set");
                    }
                    else
                    {
                        binaryMsg = Encryptor.EncryptMessage(binaryMsg);
                    }
                }

                // write the raw message
                this.WriteBytes(binaryMsg);
            }

            // switch on encryption
            if (msg.StatusMsg == StatusMessage.Encrypt)
            {
                encrypted = true;
            }
        }
Exemplo n.º 2
0
        /// <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="stream">The message stream</param>
        /// <param name="streamId">A GUID identifying this connection</param>
        public bool ProcessMessage(IpcStream stream, Guid streamId)
        {
            IpcMessage msg = stream.ReadMessage();

            // this was a close-connection notification
            if (msg.StatusMsg == StatusMessage.CloseConnection)
            {
                return(false);
            }
            // or this is just a keepalive ping
            else if (msg.StatusMsg == StatusMessage.Ping)
            {
                return(true);
            }

            bool       processedOk = false;
            string     error       = "";
            object     rv          = null;
            IpcMessage returnMsg   = new IpcMessage();

            // find the service
            if (services.TryGetValue(msg.Service, out object instance) && instance != null)
            {
                // double check method existence against type-list for security
                // typelist will contain interfaces instead of instances
                if (types[msg.Service].GetMethod(msg.Method) != null)
                {
                    // separate handling for stateful service
                    if (instance is StatefulProxy)
                    {
                        try
                        {
                            // invoke method
                            System.Reflection.MethodInfo method =
                                (instance as StatefulProxy).Type.GetMethod(msg.Method);
                            if (method == null)
                            {
                                throw new InvalidOperationException("Method not found in stateful proxy");
                            }

                            rv          = (instance as StatefulProxy).Invoke(streamId, method, msg.Parameters);
                            processedOk = true;

                            // check if encryption is required
                            if (Attribute.IsDefined(method, typeof(EncryptIfTrueAttribute)) &&
                                (bool)rv == true)
                            {
                                returnMsg.StatusMsg = StatusMessage.Encrypt;
                            }
                        }
                        catch (Exception e) { error = e.ToString(); }
                    }
                    else
                    {
                        // get the method
                        System.Reflection.MethodInfo method = instance.GetType().GetMethod(msg.Method);
                        if (method != null)
                        {
                            try
                            {
                                // invoke method
                                rv          = method.Invoke(instance, msg.Parameters);
                                processedOk = true;

                                // check if encryption is required
                                if (Attribute.IsDefined(method, typeof(EncryptIfTrueAttribute)) &&
                                    (bool)rv == true)
                                {
                                    returnMsg.StatusMsg = StatusMessage.Encrypt;
                                }
                            }
                            catch (Exception e) { error = e.ToString(); }
                        }
                        else
                        {
                            error = "Could not find method";
                        }
                    }
                }
                else
                {
                    error = "Could not find method in type";
                }
            }
            else
            {
                error = "Could not find service";
            }

            // return either return value or error message
            if (processedOk)
            {
                returnMsg.Return = rv;
            }
            else
            {
                returnMsg.Error     = error;
                returnMsg.StatusMsg = StatusMessage.None;
            }

            stream.WriteMessage(returnMsg);

            // if there's more to come, keep reading a next message
            if (msg.StatusMsg == StatusMessage.KeepAlive)
            {
                return(true);
            }
            else // otherwise close the connection
            {
                return(false);
            }
        }