예제 #1
0
        /// <summary>
        /// 生成服务调用声明
        /// <remarks>本地可无需存在目标服务的代理,不支持多态</remarks>
        /// </summary>
        /// <param name="serviceTypeName">目标服务类型全名</param>
        /// <param name="methodName">目标方法名</param>
        /// <param name="arguments">参数组</param>
        /// <returns></returns>
        public ServiceCall GenerateServiceCall(string serviceTypeName, string methodName, IDictionary <string, object> arguments)
        {
            ServiceInfo service = this.ServiceTable.Services.FirstOrDefault(o =>
                                                                            o.Name.Equals(serviceTypeName, StringComparison.InvariantCultureIgnoreCase));

            if (service == null)
            {
                throw new ServiceException(string.Format(
                                               "当前服务节点不存在类型为{0}的服务配置信息"
                                               , serviceTypeName));
            }

            var call = new ServiceCall()
            {
                TargetMethod = methodName, Identity = this.Configuration.ID
            };

            if (arguments != null)
            {
                var args = new List <ServiceCallArgument>();
                arguments.ToList().ForEach(o => args.Add(new ServiceCallArgument(o.Key, this._serializer.Serialize(o.Value))));
                call.ArgumentCollection = args.ToArray();
            }
            //根据负载算法选取适合的服务配置
            call.Target = this.Resolve <ILoadBalancingHelper>().GetServiceConfig(service
                                                                                 , call.TargetMethod
                                                                                 , call.ArgumentCollection);
            return(call);
        }
예제 #2
0
        /// <summary>
        /// 生成服务调用声明
        /// <remarks>用于本地存在目标服务代理的调用声明,支持多态参数</remarks>
        /// </summary>
        /// <param name="serviceType">目标服务类型</param>
        /// <param name="methodName">目标方法名</param>
        /// <param name="arguments">参数组</param>
        /// <returns></returns>
        public ServiceCall GenerateServiceCall(Type serviceType, string methodName, params Tuple <string, Type, object>[] arguments)
        {
            ServiceInfo service = this.ServiceTable.Services.FirstOrDefault(o =>
                                                                            o.Type != null && o.Type.Equals(serviceType));

            if (service == null)
            {
                throw new ServiceException(string.Format(
                                               "当前服务节点不存在类型为{0}的服务配置信息"
                                               , serviceType.FullName));
            }

            var call = new ServiceCall()
            {
                TargetMethod = methodName, Identity = this.Configuration.ID
            };

            if (arguments != null)
            {
                var args = new List <ServiceCallArgument>();
                //多态序列化
                arguments.ToList().ForEach(o =>
                                           args.Add(new ServiceCallArgument(o.V1, this._serializer.Serialize(o.V3, o.V2))));
                call.ArgumentCollection = args.ToArray();
            }
            //根据负载算法选取适合的服务配置
            call.Target = this.Resolve <ILoadBalancingHelper>().GetServiceConfig(service
                                                                                 , call.TargetMethod
                                                                                 , call.ArgumentCollection);
            return(call);
        }
예제 #3
0
        /// <summary>
        /// 执行服务调用
        /// <remarks>自动根据服务位置进行调用</remarks>
        /// </summary>
        /// <param name="call">调用声明</param>
        /// <param name="returnType">期望的返回值类型</param>
        /// <returns></returns>
        /// <exception cref="ServiceException"></exception>
        public object Invoke(ServiceCall call, Type returnType)
        {
            Type type;

            return(this.IsLocal(call.Target.HostUri)
                ? this.InvokeLocal(call, out type)
                : this._serializer.Deserialize(returnType, this.InvokeRemote(call)));
        }
예제 #4
0
        /// <summary>
        /// 执行服务调用,返回序列化结果
        /// </summary>
        /// <param name="call">调用声明</param>
        /// <returns></returns>
        public string InvokeSerialized(ServiceCall call)
        {
            Type returnType;

            return(this.IsLocal(call.Target.HostUri)
                ? this._serializer.Serialize(this.InvokeLocal(call, out returnType), returnType)
                : this.InvokeRemote(call));
        }
예제 #5
0
        public string Invoke(C_NSF.ServiceCall call)
        {
            var f = this.GetFacade(call.Target.HostUri);

            return(this.Is_C_NSF(f)
                ? (f as C_NSF.Remoting.RemoteFacade).Invoke(call)
                : (f as T_NSF.Remoting.RemoteFacade).Invoke(this.Parse(call)));
        }
예제 #6
0
        /// <summary>
        /// 异步执行服务调用
        /// <remarks>客户端/节点内异步</remarks>
        /// </summary>
        /// <param name="call"></param>
        /// <exception cref="ServiceException"></exception>
        public void InvokeAsync(ServiceCall call)
        {
            this.Resolve <IAsyncHandle>().Handle(call);

            this._log.DebugFormat("在当前节点发起对服务{0}|{1}|{2}的异步调用请求"
                                  , call.Target.Name
                                  , call.TargetMethod
                                  , call.Target.HostUri);
        }
예제 #7
0
        /// <summary>
        /// 在指定节点执行异步调用
        /// </summary>
        /// <param name="at">指定执行该异步调用的节点地址</param>
        /// <param name="call">调用声明</param>
        public void AsyncInvokeAt(Uri at, ServiceCall call)
        {
            this.Resolve <IRemoteHandle>().SendAnAsyncCall(at, call);

            this._log.DebugFormat("向节点{0}发送对服务{1}|{2}|{3}的异步调用请求"
                                  , at
                                  , call.Target.Name
                                  , call.TargetMethod
                                  , call.Target.HostUri);
        }
        public virtual bool Validate(ServiceCall call)
        {
            var id = call.Identity;

            if (id == null)
                throw new Exceptions.ServiceException("Identity不能为空");
            return !string.IsNullOrEmpty(id.AuthKey)
                && !string.IsNullOrEmpty(id.Source)
                && System.Web.Security.FormsAuthentication
                .HashPasswordForStoringInConfigFile(id.Source, "MD5")
                .Equals(id.AuthKey, StringComparison.InvariantCultureIgnoreCase);
        }
예제 #9
0
 private T_NSF.ServiceCall Parse(C_NSF.ServiceCall call)
 {
     return(new T_NSF.ServiceCall()
     {
         TargetMethod = call.TargetMethod,
         Identity = new T_NSF.Identity()
         {
             AuthKey = call.Identity.AuthKey, Source = call.Identity.Source
         },
         Target = this.Parse(call.Target),
         ArgumentCollection = call.ArgumentCollection.Select(o => new T_NSF.ServiceCallArgument(o.Key, o.Value)).ToArray()
     });
 }
예제 #10
0
 //本地调用记录
 private void LogLocalInvoke(ServiceCall call, bool success)
 {
     this._log.InfoFormat("【本地服务调用{0}】服务:{1}.{2},身份:{3}|{4},参数:{5}"
                          , success ? "记录" : "失败"
                          , call.Target.Name
                          , call.TargetMethod
                          , call.Identity.Source
                          , call.Identity.AuthKey
                          , string.Join("$"
                                        , call.ArgumentCollection.Select(o => string.Format("{0}={1}"
                                                                                            , o.Key
                                                                                            , o.Value)).ToArray()));
 }
예제 #11
0
        public void SendAnAsyncCall(Uri uri, C_NSF.ServiceCall call)
        {
            var f = this.GetFacade(uri);

            if (this.Is_C_NSF(f))
            {
                (f as C_NSF.Remoting.RemoteFacade).InvokeAsync(call);
            }
            else
            {
                (f as T_NSF.Remoting.RemoteFacade).InvokeAsync(this.Parse(call));
            }
        }
예제 #12
0
        public virtual bool Validate(ServiceCall call)
        {
            var id = call.Identity;

            if (id == null)
            {
                throw new Exceptions.ServiceException("Identity不能为空");
            }
            return(!string.IsNullOrEmpty(id.AuthKey) &&
                   !string.IsNullOrEmpty(id.Source) &&
                   System.Web.Security.FormsAuthentication
                   .HashPasswordForStoringInConfigFile(id.Source, "MD5")
                   .Equals(id.AuthKey, StringComparison.InvariantCultureIgnoreCase));
        }
예제 #13
0
        //HACK:缺少参数自动用null填充
        private object ParseArgument(System.Reflection.ParameterInfo p, ServiceCall call)
        {
            var arg = call.ArgumentCollection.FirstOrDefault(o =>
                                                             o.Key.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase));

            if (arg == null)
            {
                throw new ServiceException(string.Format("缺少参数{0}", p.Name), ExceptionCode.ArgumentError);
            }

            //HACK:此处针对string的json序列化优化处理,以避免http调用情况下的字符串参数兼容问题和意外不合法反序列化
            if (p.ParameterType == typeof(string))
            {
                if (string.IsNullOrEmpty(arg.Value) && this.InternalDebug("返回空字符串"))
                {
                    return(arg.Value);
                }
                if (arg.Value.Equals("null", StringComparison.InvariantCultureIgnoreCase) && this.InternalDebug("遇到null,返回空"))
                {
                    return(null);
                }
                if (!arg.Value.StartsWith("\"") && this.InternalDebug("返回非\"开头,返回原始字符串"))
                {
                    return(arg.Value);
                }
            }

            try
            {
                return(this._serializer.Deserialize(p.ParameterType, arg.Value));
            }
            catch (Exception e)
            {
                //HACK:例外处理 string类型反序列化失败时,直接返回该字符串
                //if (p.ParameterType == typeof(string))
                //    return arg.Value;
                throw new ServiceException(string.Format("参数{0}格式不正确:{1}"
                                                         , p.Name
                                                         , e.Message)
                                           , ExceptionCode.ArgumentError
                                           , e);
            }
        }
 public void Handle(ServiceCall call, Type returnType, Action<object> callback)
 {
     throw new NotImplementedException("未提供带回调的异步处理实现");
 }
 public void Handle(ServiceCall call)
 {
     throw new NotImplementedException("未提供异步处理实现");
 }
 public void Handle(ServiceCall call, Type returnType, Action <object> callback)
 {
     throw new NotImplementedException("未提供带回调的异步处理实现");
 }
 public void Handle(ServiceCall call)
 {
     throw new NotImplementedException("未提供异步处理实现");
 }
예제 #18
0
 public void InvokeAsync(ServiceCall call, Type returnType, Action <object> callback)
 {
     this.Resolve <IAsyncHandle>().Handle(call, returnType, callback);
 }
예제 #19
0
        //本地服务调用
        private object InvokeLocal(ServiceCall call, out Type returnType)
        {
            if (!this.Resolve <IAuthentication>().Validate(call))
            {
                throw new ServiceException(string.Format("调用者身份认证失败:{0}|{1}"
                                                         , call.Identity == null ? null : call.Identity.Source
                                                         , call.Identity == null ? null : call.Identity.AuthKey)
                                           , ExceptionCode.NoPermission);
            }

            #region ServiceCall验证
            if (call.Target == null)
            {
                throw new ServiceException("Target不能为空");
            }
            if (call.Target.Type == null)
            {
                throw new ServiceException(string.Format("当前节点不存在服务类型:{0},{1}"
                                                         , call.Target.Name
                                                         , call.Target.AssemblyName)
                                           , ExceptionCode.ServiceNotFound);
            }
            var target = this._container.Resolve(call.Target.Type);
            if (target == null)
            {
                throw new ServiceException(string.Format("未在容器中找到目标服务{0}"
                                                         , call.Target.Type.FullName)
                                           , ExceptionCode.ServiceNotFound);
            }
            var method = call.Target.Type.GetMethods()
                         .FirstOrDefault(o => o.Name.Equals(call.TargetMethod, StringComparison.InvariantCultureIgnoreCase));
            if (method == null)
            {
                throw new ServiceException(string.Format("未在类型{0}中找到名为{1}的公开方法"
                                                         , call.Target.Type.FullName
                                                         , call.TargetMethod)
                                           , ExceptionCode.MethodNotFound);
            }
            #endregion

            try
            {
                //参数检查
                var args = from p in method.GetParameters() select this.ParseArgument(p, call);

                returnType = method.ReturnType;
                //TODO:Fast Invoker
                var result = method.Invoke(target, args.ToArray());
                this.LogLocalInvoke(call, true);
                return(result);
            }
            catch (Exception e)
            {
                this.LogLocalInvoke(call, false);

                if (e is ServiceException)
                {
                    throw e;
                }
                //返回内部异常信息
                throw new ServiceException((e.InnerException ?? e).Message, e.InnerException ?? e);
            }
        }
예제 #20
0
 //远程服务调用
 private string InvokeRemote(ServiceCall call)
 {
     return(this._remoteHandle.Invoke(call));
 }
예제 #21
0
 /// <summary>
 /// 执行服务调用
 /// <remarks>自动根据服务位置进行调用</remarks>
 /// </summary>
 /// <typeparam name="T">期望的返回值类型</typeparam>
 /// <param name="call">调用声明</param>
 /// <returns></returns>
 /// <exception cref="ServiceException"></exception>
 public T Invoke <T>(ServiceCall call)
 {
     return((T)this.Invoke(call, typeof(T)));
 }