Ejemplo n.º 1
0
        private async Task DispatchRpcMethod(RequestContext context)
        {
            if (!ValidateRequest(context))
            {
                return;
            }
            JsonRpcMethod method;

            try
            {
                if (Contract.Methods.TryGetValue(context.Request.Method, out var candidates))
                {
                    method = MethodBinder.TryBindToMethod(candidates, context);
                }
                else
                {
                    TrySetErrorResponse(context, JsonRpcErrorCode.MethodNotFound,
                                        $"Method \"{context.Request.Method}\" is not found.");
                    return;
                }
            }
            catch (AmbiguousMatchException)
            {
                TrySetErrorResponse(context, JsonRpcErrorCode.InvalidParams,
                                    $"Invocation of method \"{context.Request.Method}\" is ambiguous.");
                return;
            }
            if (method == null)
            {
                TrySetErrorResponse(context, JsonRpcErrorCode.InvalidParams,
                                    $"Cannot find method \"{context.Request.Method}\" with matching signature.");
                return;
            }
            // Parse the arguments
            object[] args;
            try
            {
                args = MethodBinder.BindParameters(method.Parameters, context);
            }
            catch (Exception ex)
            {
                TrySetErrorResponse(context, JsonRpcErrorCode.InvalidParams, ex.Message);
                if (context.Response != null)
                {
                    context.Response.Error = ResponseError.FromException(ex, true);
                }
                return;
            }
            // Call the method
            try
            {
                var result = await method.Invoker.InvokeAsync(context, args).ConfigureAwait(false);

                // Produce the response.
                if (context.Response != null && context.Response.Result == null && context.Response.Error == null)
                {
                    if (result is ResponseError err)
                    {
                        context.Response.Error = err;
                    }
                    else
                    {
                        context.Response.Result = method.ReturnParameter.Converter.ValueToJson(result);
                        // JValue(null) is not `null`
                        Debug.Assert(context.Response.Result != null);
                    }
                }
            }
            catch (JsonRpcException ex)
            {
                if (context.Response != null)
                {
                    context.Response.Result = null;
                    context.Response.Error  = ex.Error;
                }
            }
            // Let other exceptions bubble up. We will handle them in the pipe, or finally in InvokePipeline.
        }