/// <summary> /// 获取服务方法反射信息 /// </summary> /// <param name="request">请求消息</param> /// <returns>方法反射信息</returns> protected MethodReflectionInfo EnsureMethodInfo(MessageRequest request) { var serviceInfo = _serverStub.GetServiceInfo(request.Service); if (serviceInfo == null) { throw new RpcInternalException($"The service {request.Service} is not found."); } List <Type> types = new List <Type>(); for (int i = 0; i < request.ArgTypes?.Count; i++) { types.Add(Type.GetType(request.ArgTypes[i])); } MethodReflectionInfo methodInfo = serviceInfo.EnsureMethodInfo(request.Method, request.Args?.ToArray(), types.ToArray(), request.Args?.Count ?? 0); if (methodInfo == null) { throw new RpcInternalException($"The parameters of service method {request.Method} is unmatch. Parameters:{(request.ArgTypes == null ? "" : string.Join("; ", request.ArgTypes))}"); } return(methodInfo); }
/// <summary> /// 调用入口 /// </summary> /// <param name="binder">请求的绑定对象</param> /// <param name="args">参数集合</param> /// <param name="result">返回结果</param> /// <returns></returns> public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { //处理参数 MethodReflectionInfo methodInfo = _serviceInfo.EnsureMethodInfo(binder.Name, args, null, binder.CallInfo.ArgumentCount); //序列化消息数据 bool isExisted = _clientStub.TraceChain.GetCurrentTraceContext() != null; var request = new MessageRequest { MessageId = Guid.NewGuid().ToString(), TraceContext = isExisted ? _clientStub.TraceChain.GetCurrentTraceContext() : _clientStub.TraceChain.Begin(), Service = _serviceInfo.ServiceType.Name, Method = binder.Name, ClusterToken = _clientStub.ClusterToken, ArgTypes = methodInfo.Parameters.Any() ? new List <string>() : null, Args = methodInfo.Parameters.Any() ? new List <object>() : null }; for (int i = 0; i < methodInfo.Parameters.Length; i++) { request.ArgTypes.Add(methodInfo.Parameters[i].ParameterType.AssemblyQualifiedName); //todo 但继承的子类不在同个程序集的时候无法反射 request.Args.Add(args[i]); } TProtocol message = SerializeMessage(request); result = null; if (_clientStub.EnableServiceDiscovery) { bool success = InvokeTolerably(request.MessageId, message, out Exception lastException, out object ret); if (!success && lastException != null) { throw lastException; } result = ret; } else { MessageResponse response = Invoke(request.MessageId, message, _clientStub.EndPoint); result = response.Data; } if (methodInfo.IsAwaitable) //处理异步返回值 { if (methodInfo.ReturnType.IsGenericType) { Type genericParamType = methodInfo.Method.ReturnType.GenericTypeArguments.First(); dynamic value = Utility.ChangeType(result, genericParamType); if (value == null) { result = Utility.GetTaskByType(genericParamType); } else { result = Task.FromResult(value); } } else { result = Task.CompletedTask; } } //完成链路 if (!isExisted) { _clientStub.TraceChain.Finish(); } return(true); }
/// <summary> /// 请求调用 /// </summary> /// <param name="buffer">已序列化的消息请求</param> /// <returns>序列化消息</returns> public async Task <TProtocol> InvokeAsync(TProtocol buffer) { MessageResponse response = new MessageResponse(); try { Dictionary <string, object> logs = new Dictionary <string, object>(); MessageRequest request = DeserializeMessage(buffer); try { if (request.ClusterToken != _clusterToken) { throw new IllegalClusterTokenException($"Cluster token({request.ClusterToken}) is illegal."); } MethodReflectionInfo methodInfo = EnsureMethodInfo(request); var serviceInstance = _serverStub.GetServiceInstance(request.Service); object result = null; object ret = methodInfo.Method.Invoke(serviceInstance, request.Args?.ToArray()); if (methodInfo.IsAwaitable) //处理异步 { dynamic task = (Task)ret; if (methodInfo.ReturnType.IsGenericType) { result = await task.ConfigureAwait(false); } else { await task.ConfigureAwait(false); } } else { result = ret; } response.MessageId = request.MessageId; response.Data = result; response.ReturnType = result?.GetType()?.AssemblyQualifiedName; response.Success = true; return(SerializeMessage(response)); } catch (Exception ex) { logs.Add(TextLog.ExceptionKey, ex); throw; } finally { logs.Add(TextLog.MethodNameKey, request?.Method); logs.Add(TextLog.LogTimeKey, DateTime.Now); logs.Add(TextLog.TraceIdKey, request?.TraceContext?.TraceId); logs.Add(nameof(TraceContext.SpanId), request?.TraceContext?.SpanId); if (logs.ContainsKey(TextLog.ExceptionKey)) { _logger.WriteErrorLog(logs); } else { _logger.WriteInfoLog(logs); } } } catch (Exception ex) { response.Message = ex.InnerException != null ? ex.InnerException.Message : ex.Message; _logger.WriteErrorLog(ex); } return(SerializeMessage(response)); }
/// <summary> /// 序列化消息请求体 /// </summary> /// <param name="obj">消息请求体</param> /// <returns>消息协议泛型</returns> protected abstract TProtocol SerializeMessage(MessageRequest obj);