/// <summary>
        /// Called when an invoke method call has been received.
        /// </summary>
        /// <param name="socket">The web-socket of the client that wants to invoke a method.</param>
        /// <param name="invocationDescriptor">
        /// The invocation descriptor containing the method name and parameters.
        /// </param>
        /// <returns>Awaitable Task.</returns>
        public override async Task <object> OnInvokeMethodReceivedAsync(object sender, InvocationDescriptor invocationDescriptor)
        {
            // there must be a separator in the method name.
            if (!invocationDescriptor.MethodName.Contains(Separator))
            {
                throw new Exception($"Invalid controller or method name '{invocationDescriptor.MethodName}'.");
            }

            // find the controller and the method name.
            string[] names      = invocationDescriptor.MethodName.Split(Separator);
            string   controller = names[0].ToLower();
            string   command    = Prefix + names[1];

            // find the desired controller.
            if (Controllers.TryGetValue(controller, out object self))
            {
                // use reflection to find the method in the desired controller.
                MethodInfo method = self.GetType().GetMethod(command);

                // if the method could not be found:
                if (method == null)
                {
                    throw new Exception($"Received unknown command '{command}' for controller '{controller}'.");
                }

                List <object> args = new List <object>();
                if (invocationDescriptor.Params is JArray)
                {
                    JArray array = (JArray)invocationDescriptor.Params;
                    args = array.ToObject <List <object> >();
                }
                else if (invocationDescriptor.Params is JObject)
                {
                    args.Add(invocationDescriptor.Params as object);
                }
                if (!NoWebsocketArgument)
                {
                    args.Insert(0, sender);
                }

                // call the method asynchronously.
                try
                {
                    return(await Task.Run(() => method.Invoke(self, args.ToArray())));
                }
                catch (TargetInvocationException ex)
                {
                    throw ex.InnerException;
                }
            }
            else
            {
                throw new Exception($"Received command '{command}' for unknown controller '{controller}'.");
            }
        }
 /// <summary>
 /// Called when an invoke method call has been received.
 /// </summary>
 /// <param name="socket">The web-socket of the client that wants to invoke a method.</param>
 /// <param name="invocationDescriptor">
 /// The invocation descriptor containing the method name and parameters.
 /// </param>
 /// <returns>Awaitable Task.</returns>
 public virtual Task <object> OnInvokeMethodReceivedAsync(object sender, InvocationDescriptor invocationDescriptor)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Called when an invoke method call has been received.
        /// </summary>
        /// <param name="socket">The web-socket of the client that wants to invoke a method.</param>
        /// <param name="invocationDescriptor">
        /// The invocation descriptor containing the method name and parameters.
        /// </param>
        /// <returns>Awaitable Task.</returns>
        public override async Task <object> OnInvokeMethodReceivedAsync(object sender, InvocationDescriptor invocationDescriptor)
        {
            // create the method name that has to be found.
            string command = Prefix + invocationDescriptor.MethodName;

            // use reflection to find the method in the desired controller.
            MethodInfo method = Controller.GetType().GetMethod(command);

            // if the method could not be found:
            if (method == null)
            {
                throw new Exception($"Received unknown command '{command}' for controller '{Controller.GetType().Name}'.");
            }
            List <object> args = new List <object>();

            if (invocationDescriptor.Params is JArray)
            {
                // Case 1: Params is array {"jsonrpc": "2.0", "id": 1, "method": "method", "params": [ 23, "minuend", 42]}
                JArray array = (JArray)invocationDescriptor.Params;
                args = array.ToObject <List <object> >();
            }
            else if (invocationDescriptor.Params is JObject)
            {
                // Case 2: Params is JObject {"jsonrpc": "2.0", "id": 1, "method": "method", "params": { "a": 23, "b": "1234"}}
                args.Add(invocationDescriptor.Params as object);
            }
            else
            {
                // Case 3: Params is basic object {"jsonrpc": "2.0", "id": 1, "method": "method", "params": "Happy New Year"}
                args.Add(invocationDescriptor.Params as object);
            }
            if (!NoWebsocketArgument)
            {
                args.Insert(0, sender);
            }
            // call the method asynchronously.
            try
            {
                // invoke the method and get the result.
                InvocationResult invokeResult = new InvocationResult()
                {
                    MethodName = invocationDescriptor.MethodName,
                    Id         = invocationDescriptor.Id,
                    Result     = null,
                    Exception  = null
                };
                try
                {
                    invokeResult.Result = await Task.Run(() => method.Invoke(Controller, args.ToArray()));

                    if (invokeResult.Result == null)
                    {
                        return(null);
                    }
                }
                // send the exception as the invocation result if there was one.
                catch (Exception ex)
                {
                    invokeResult.Exception = new RemoteException(ex);
                }
                return(invokeResult);
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
        }
        /// <summary>
        /// Called when an invoke method call has been received.
        /// </summary>
        /// <param name="socket">The web-socket of the client that wants to invoke a method.</param>
        /// <param name="invocationDescriptor">
        /// The invocation descriptor containing the method name and parameters.
        /// </param>
        /// <returns>Awaitable Task.</returns>
        public override async Task <object> OnInvokeMethodReceivedAsync(object sender, InvocationDescriptor invocationDescriptor)
        {
            if (!_handlers.ContainsKey(invocationDescriptor.MethodName))
            {
                throw new Exception($"Received unknown command '{invocationDescriptor.MethodName}'.");
            }
            var invocationHandler = _handlers[invocationDescriptor.MethodName];

            if (invocationHandler != null)
            {
                List <object> args = new List <object>();
                if (invocationDescriptor.Params is JArray)
                {
                    JArray array = (JArray)invocationDescriptor.Params;
                    args = array.ToObject <List <object> >();
                }
                else if (invocationDescriptor.Params is JObject)
                {
                    args.Add(invocationDescriptor.Params as object);
                }
                //if (!NoWebsocketArgument)
                //    args.Insert(0, socketId);
                return(await Task.Run(() => invocationHandler.Handler(args.ToArray())));
            }
            return(await Task.FromResult <object>(null));
        }