/// <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); }
/// <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); }
/// <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))); }
/// <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)); }
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))); }
/// <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); }
/// <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); }
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() }); }
//本地调用记录 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())); }
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)); } }
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)); }
//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 InvokeAsync(ServiceCall call, Type returnType, Action <object> callback) { this.Resolve <IAsyncHandle>().Handle(call, returnType, callback); }
//本地服务调用 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); } }
//远程服务调用 private string InvokeRemote(ServiceCall call) { return(this._remoteHandle.Invoke(call)); }
/// <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))); }