コード例 #1
0
 /// <summary>
 /// Static constructor
 ///
 /// Initialise the available RPC methods by inspecting the class
 /// </summary>
 static RpcConnection()
 {
     // Find all methods on the instance decorated with the RpcCall attribute
     foreach (MethodInfo method in typeof(RpcConnection).GetRuntimeMethods())
     {
         // Is the method marked for RPC export ?
         RpcExport exported = null;
         foreach (object attribute in method.GetCustomAttributes(true))
         {
             if (attribute is RpcExport)
             {
                 exported = (RpcExport)attribute;
                 break;
             }
         }
         if (exported == null)
         {
             continue;
         }
         // Build up information about the call
         RpcMethod methodInfo = new RpcMethod();
         methodInfo.Method   = method;
         methodInfo.Exported = exported;
         ParameterInfo[] args = method.GetParameters();
         methodInfo.Arguments = new string[args.Length];
         for (int i = 0; i < args.Length; i++)
         {
             methodInfo.Arguments[i] = args[i].Name;
         }
         // Add it to the cache (TODO: Should check for duplicates)
         s_functionCache.Add(methodInfo.Exported.FunctionName, methodInfo);
     }
 }
コード例 #2
0
 /// <summary>
 /// Static constructor
 /// 
 /// Initialise the available RPC methods by inspecting the class
 /// </summary>
 static RpcConnection()
 {
     // Find all methods on the instance decorated with the RpcCall attribute
     foreach (MethodInfo method in typeof(RpcConnection).GetRuntimeMethods())
     {
         // Is the method marked for RPC export ?
         RpcExport exported = null;
         foreach (object attribute in method.GetCustomAttributes(true))
             if (attribute is RpcExport)
             {
                 exported = (RpcExport)attribute;
                 break;
             }
         if (exported == null)
             continue;
         // Build up information about the call
         RpcMethod methodInfo = new RpcMethod();
         methodInfo.Method = method;
         methodInfo.Exported = exported;
         ParameterInfo[] args = method.GetParameters();
         methodInfo.Arguments = new string[args.Length];
         for (int i = 0; i < args.Length; i++)
             methodInfo.Arguments[i] = args[i].Name;
         // Add it to the cache (TODO: Should check for duplicates)
         s_functionCache.Add(methodInfo.Exported.FunctionName, methodInfo);
     }
 }
コード例 #3
0
        /// <summary>
        /// Process an RPC call
        ///
        /// This implementation is very manual but is probably enough for the very
        /// small set of API calls we support.
        /// </summary>
        /// <param name="data"></param>
        private void ProcessRpcCall(IDictionary <string, object> data)
        {
            Dictionary <string, object> result = new Dictionary <string, object>();

            result[FunctionSequence] = data[FunctionSequence];
            try
            {
                // Is it a valid function name ?
                if (!s_functionCache.ContainsKey(data[FunctionName].ToString()))
                {
                    throw new RpcException(String.Format("Unsupported or unrecognised function '{0}'", data[FunctionName]));
                }
                // Verify the arguments are at least a dictionary
                IDictionary <string, object> args = data[FunctionParameters] as IDictionary <string, object>;
                if (args == null)
                {
                    throw new RpcException("Incorrectly formed RPC request");
                }
                // Are all the required arguments present ?
                RpcMethod method = s_functionCache[data[FunctionName].ToString()];
                if (!ContainsKeys(args, method.Arguments))
                {
                    throw new RpcException("One or more required arguments are missing.");
                }
                if (method.Arguments.Length != args.Count)
                {
                    throw new RpcException("Unexpected additional arguments were provided.");
                }
                // Is authentication required ?
                if (method.Exported.AuthenticationRequired && !m_authenticated)
                {
                    throw new RpcException("Authentication required");
                }
                // Map named parameters to an array for invokation
                object[] callParams = new object[method.Arguments.Length];
                for (int i = 0; i < method.Arguments.Length; i++)
                {
                    callParams[i] = args[method.Arguments[i]];
                }
                // Finally, call the method
                result[CallResult] = method.Method.Invoke(this, callParams);
                result[CallStatus] = true;
            }
            catch (Exception ex)
            {
                result[CallStatus] = false;
                result[CallResult] = ex.Message;
            }
            // Finally we can send back the response
            string json = JsonParser.ToJson(result);

            lock (m_socket)
            {
                m_socket.Send(json);
            }
        }