Ejemplo n.º 1
0
        /// <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)
                {
                    _logger.WriteErrorLog(ex);
                    throw;
                }
                finally
                {
                }
            }
            catch (Exception ex)
            {
                response.Message = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
                _logger.WriteErrorLog(ex);
            }
            return(SerializeMessage(response));
        }
Ejemplo n.º 2
0
        /// <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);

            //序列化消息数据
            var request = new MessageRequest
            {
                MessageId    = Guid.NewGuid().ToString(),
                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);
            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);
                    result = Utility.GetTaskByType(genericParamType, value);
                }
                else
                {
                    result = Task.CompletedTask;
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 获取服务信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static ServiceReflectionInfo GetServiceInfo(Type type)
        {
            var info = new ServiceReflectionInfo()
            {
                ServiceType = type, Attributes = type.GetCustomAttributes().ToList()
            };
            var methods        = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            var methodInfoList = new List <MethodReflectionInfo>();

            foreach (var method in methods)
            {
                var mInfo = new MethodReflectionInfo()
                {
                    Attributes  = method.GetCustomAttributes().ToList(),
                    Method      = method,
                    Parameters  = method.GetParameters(),
                    ReturnType  = method.ReturnType,
                    IsAwaitable = method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null
                };
                methodInfoList.Add(mInfo);
            }
            info.Methods = methodInfoList;
            return(info);
        }