/// <summary> /// 调用处理RpcRequest的方法 /// </summary> /// <param name="requestContext">待处理的请求方法</param> /// <param name="rpcContext">Rpc方法中获得的可选上下文</param> /// <param name="callback">回调方法</param> /// <returns></returns> public JsonRpcResponseContext Handle(JsonRpcRequestContext requestContext, Object rpcContext = null, Action <JsonRpcResponseContext> callback = null) { //回调函数初始 if (callback == null) { callback = delegate(JsonRpcResponseContext item) { } } ; //添加到线程Id->上下文集合中 AddRpcContext(rpcContext); //初始化当前线程数据上下文 //JsonRpcDataContext.GetOrInitCurrentContext(); //将请求上下文Tags赋值到线程上下文中 foreach (var key in requestContext.Tags.Keys) { JsonRpcDataContext.SetContextItem(key, requestContext.Tags[key]); } #region 预处理&出错则回调直接返回 var preProcessingException = PreProcess(requestContext, rpcContext); if (preProcessingException != null) { var response = new JsonRpcResponseContext() { Error = preProcessingException, Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } #endregion #region 获取和验证请求的委托与meta信息 //当前请求方法对应的meta信息 SMDService metaData = null; //当前请求方法对应的反射委托 Delegate handle = null; //根据请求方法,获取方法对应的委托 var haveDelegate = Handlers.TryGetValue(requestContext.Method, out handle); //根据请求方法,获取方法对应的meta信息 var haveMetadata = MetaData.Services.TryGetValue(requestContext.Method, out metaData); if (haveDelegate == false || haveMetadata == false || metaData == null || handle == null) { var response = new JsonRpcResponseContext() { Result = null, Error = new JsonRpcException(-32601, "方法未找到", "此方法 " + requestContext.Method + " 不存在或未部署", requestContext), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); } #endregion #region 参数获取与校验 bool isJObject = requestContext.Params is JObject; bool isJArray = requestContext.Params is JArray; //请求方法参数 object[] parameters = null; //metaData是否包含异常 bool expectsRefException = false; //metaData 参数数量 var metaDataParamCount = metaData.parameters.Count(p => p != null); //获取当前请求上下问参数集合 var paramCollection = requestContext.Params as ICollection; int paramCount = 0, loopCount = 0; if (paramCollection != null) { paramCount = loopCount = paramCollection.Count; } //在请求参数与metaData参数相差一情况下,判断metaData最后参数是否为异常 if (paramCount == metaDataParamCount - 1 && metaData.parameters[metaDataParamCount - 1].ObjectType.Name.Contains(typeof(JsonRpcException).Name)) { paramCount++; expectsRefException = true; } //初始化请求参数集合大小 parameters = new object[paramCount]; //根据请求参数不同类型,填充参数集合 if (isJArray) { var jArray = requestContext.Params as JArray; for (int i = 0; i < loopCount; i++) { parameters[i] = ConvetParameter(jArray[i], metaData.parameters[i]); } } else if (isJObject) { var jObject = requestContext.Params as JObject; var tokenDict = jObject as IDictionary <string, JToken>; parameters = new object[metaData.parameters.Length]; //将请求参数与服务定义参数进行比较 for (int i = 0; i < metaData.parameters.Length; i++) { if (tokenDict.ContainsKey(metaData.parameters[i].Name) == false) { var response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32602, "无效参数", string.Format("参数 '{0}' 未定义", metaData.parameters[i].Name), requestContext)), Id = requestContext.Id }; } //获取请求参数 parameters[i] = ConvetParameter(jObject[metaData.parameters[i].Name], metaData.parameters[i]); } } //请求参数小于metaData参数,可能包含可选参数 if (parameters.Length < metaDataParamCount && metaData.defaultValues.Length > 0) { //请求参数提供的数量 var suppliedParamsCount = parameters.Length; //非Rpc设置的可选参数数量,缺失的参数数量 var missingParamsCount = metaDataParamCount - parameters.Length; //调整可选参数数组大小,用于包含所有可选参数 Array.Resize(ref parameters, parameters.Length + missingParamsCount); //将所有参数填充到parameters中 for (int paramIndex = parameters.Length - 1, defaultIndex = metaData.defaultValues.Length - 1; paramIndex >= suppliedParamsCount && defaultIndex >= 0; paramIndex--, defaultIndex--) { parameters[paramIndex] = metaData.defaultValues[defaultIndex].Value; } if (missingParamsCount > metaData.defaultValues.Length) { var response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32602, "无效参数", string.Format("缺省参数数量 {0} 不足以填充所缺失的参数数量 {1}", metaData.defaultValues.Length, missingParamsCount), requestContext)), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } } if (parameters.Length != metaDataParamCount) { var response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32602, "无效参数", string.Format("应接收 {0} 个参数,实际接收到 {1}", metaData.parameters.Length, parameters.Length), requestContext)), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } #endregion #region 调用 try { //将回调存储到当前线程中,,便于从GetAsyncCallback中获得以进行回调 Thread.SetData(Thread.GetNamedDataSlot(THREAD_CALLBACK_SLOT_NAME), callback); //调用请求方法对应委托并传入参数 var results = handle.DynamicInvoke(parameters); //当前线程包含异常 if (Task.CurrentId.HasValue && rpcExceptions.TryRemove(Task.CurrentId.Value, out JsonRpcException contextException)) { var response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, contextException), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } var lastParam = parameters.LastOrDefault(); if (expectsRefException && lastParam != null && lastParam is JsonRpcException) { var response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, lastParam as JsonRpcException), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } //返回结果 var reponse = new JsonRpcResponseContext() { Result = results }; CompletedProcess(requestContext, reponse, requestContext); return(reponse); } catch (Exception ex) { JsonRpcResponseContext response = null; //系统委托调用异常(参数不匹配) if (ex is TargetParameterCountException) { response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32602, "参数不匹配", ex, rpcContext)) }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } //业务异常 if (ex is JsonRpcException) { response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32603, "内部错误", ex.InnerException, rpcContext)), Id = requestContext.Id }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } //内部异常为业务异常 if (ex.InnerException != null && ex.InnerException is JsonRpcException) { response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, ex.InnerException as JsonRpcException) }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } //内部异常 else if (ex.InnerException != null) { response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32603, "内部错误", ex.InnerException, rpcContext)) }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } //其他异常,封装返回 else { response = new JsonRpcResponseContext() { Error = ProcessException(requestContext, new JsonRpcException(-32603, "内部错误", ex, rpcContext)) }; callback.Invoke(response); CompletedProcess(requestContext, response, rpcContext); return(response); } } finally { RemoveRpcContext(); } #endregion }
public void AddService(string method, Dictionary <string, Type> parameters, Dictionary <string, object> defaultValues) { var newService = new SMDService(transport, "JSON-RPC-2.0", parameters, defaultValues); Services.Add(method, newService); }