/// <summary> /// 获取Invoke方法 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> private System.Reflection.MethodInfo GetInvokeMethod(RequestMessage reqMsg) { var method = reqMsg.MethodInfo; reqMsg.MethodInfo = null; return method; }
/// <summary> /// 调用方法 /// </summary> /// <param name="message"></param> /// <returns></returns> public InvokeData CallMethod(InvokeMessage message) { #region 设置请求信息 RequestMessage reqMsg = new RequestMessage(); reqMsg.InvokeMethod = true; reqMsg.AppName = appName; //应用名称 reqMsg.HostName = hostName; //客户端名称 reqMsg.IPAddress = ipAddress; //客户端IP地址 reqMsg.ServiceName = message.ServiceName; //服务名称 reqMsg.MethodName = message.MethodName; //方法名称 reqMsg.ReturnType = typeof(string); //返回类型 reqMsg.TransactionId = Guid.NewGuid(); //传输ID号 #endregion //给参数赋值 reqMsg.Parameters["InvokeParameter"] = message.Parameters; //调用服务 var resMsg = service.CallService(reqMsg); //如果有异常,向外抛出 if (resMsg.IsError) throw resMsg.Error; //返回数据 return resMsg.Value as InvokeData; }
/// <summary> /// 调用方法 /// </summary> /// <param name="client"></param> /// <param name="reqMsg"></param> /// <returns></returns> public ResponseMessage CallMethod(IScsServerClient client, RequestMessage reqMsg) { //创建Caller; var caller = CreateCaller(client, reqMsg); //设置上下文 SetOperationContext(client, caller); try { //处理状态服务 if (reqMsg.ServiceName == typeof(IStatusService).FullName) { var s = ParseService(reqMsg); //调用服务 return s.CallService(reqMsg); } else { //创建服务 var service = CreateService(reqMsg); //启动计时 var watch = Stopwatch.StartNew(); //调用服务 var resMsg = service.CallService(reqMsg); //停止计时 watch.Stop(); //调用参数 var callArgs = new CallEventArgs { Caller = caller, ElapsedTime = watch.ElapsedMilliseconds, Count = resMsg.Count, Error = resMsg.Error, Value = resMsg.Value }; //响应计数 NotifyEventArgs(callArgs); //如果是Json方式调用,则需要处理异常 if (resMsg.IsError && reqMsg.InvokeMethod) { resMsg.Error = new ApplicationException(callArgs.Error.Message); } return resMsg; } } finally { //初始化上下文 OperationContext.Current = null; } }
/// <summary> /// 重载调用服务 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> protected override ResponseMessage CallService(RequestMessage reqMsg) { var caller = CreateCaller(reqMsg); //上下文 SetOperationContext(caller); //调用基类方法 return base.CallService(reqMsg); }
protected void QueueError(RequestMessage reqMsg, Exception error) { if (reqMsg != null) { var resMsg = new ResponseMessage { TransactionId = reqMsg.TransactionId, ReturnType = reqMsg.ReturnType, ServiceName = reqMsg.ServiceName, MethodName = reqMsg.MethodName, Error = error }; QueueMessage(resMsg); } }
/// <summary> /// 创建AppCaller /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> private AppCaller CreateCaller(RequestMessage reqMsg) { //创建AppCaller对象 var caller = new AppCaller { AppPath = AppDomain.CurrentDomain.BaseDirectory, AppName = reqMsg.AppName, IPAddress = reqMsg.IPAddress, HostName = reqMsg.HostName, ServiceName = reqMsg.ServiceName, MethodName = reqMsg.MethodName, Parameters = reqMsg.Parameters.ToString(), CallTime = DateTime.Now }; return caller; }
/// <summary> /// 异步调用方法 /// </summary> /// <param name="reqMsg"></param> public ResponseMessage CallService(RequestMessage reqMsg) { var context = OperationContext.Current; //实例化异步调用器 var worker = smart.QueueWorkItem<OperationContext, RequestMessage, ResponseMessage> (GetResponse, context, reqMsg); //等待响应 ResponseMessage resMsg = null; try { resMsg = worker.GetResult(elapsedTime, true); } catch (Exception ex) { //结束当前线程 if (!worker.IsCompleted) worker.Cancel(true); var body = string.Format("Call service ({0}, {1}) timeout ({2}) ms. Error: {4}\r\nParameters => {3}" , reqMsg.ServiceName, reqMsg.MethodName, (int)elapsedTime.TotalMilliseconds, reqMsg.Parameters.ToString(), ex.Message); //获取异常 var error = IoCHelper.GetException(OperationContext.Current, reqMsg, body); //将异常信息写出 logger.Write(error); //处理异常 resMsg = new ResponseMessage { TransactionId = reqMsg.TransactionId, ReturnType = reqMsg.ReturnType, ServiceName = reqMsg.ServiceName, MethodName = reqMsg.MethodName, Parameters = reqMsg.Parameters, Error = error }; } //返回响应的消息 return resMsg; }
/// <summary> /// Calls the service. /// </summary> /// <param name="reqMsg">The MSG.</param> /// <returns>The msg.</returns> public ResponseMessage CallService(RequestMessage reqMsg) { //运行服务返回值 var resMsg = Run(reqMsg); //如果出错,通知客户端 if (resMsg.IsError) { string body = string.Format("Remote client【{0}】call service ({1},{2}) error.\r\nParameters => {3}\r\nMessage => {4}", reqMsg.Message, reqMsg.ServiceName, reqMsg.MethodName, reqMsg.Parameters.ToString(), resMsg.Message); //获取异常 var exception = IoCHelper.GetException(OperationContext.Current, reqMsg, body, resMsg.Error); logger.Write(exception); } return resMsg; }
/// <summary> /// 处理输入参数 /// </summary> /// <param name="reqMsg"></param> /// <param name="method"></param> private void HandleBegin(RequestMessage reqMsg, System.Reflection.MethodInfo method) { //设置Invoke方式 reqMsg.InvokeMethod = true; var pis = method.GetParameters(); if (pis.Length > 0) { if (reqMsg.Parameters.Count > 0) { string jsonString = reqMsg.Parameters.ToString(); reqMsg.Parameters.Clear(); reqMsg.Parameters["InvokeParameter"] = jsonString; } else { reqMsg.Parameters["InvokeParameter"] = null; } } }
/// <summary> /// 响应请求 /// </summary> private ResponseMessage GetResponse(OperationContext context, RequestMessage reqMsg) { try { //设置上下文 OperationContext.Current = context; //调用方法 return service.CallService(reqMsg); } catch (Exception ex) { //出现异常时返回null return null; } finally { //初始化上下文 OperationContext.Current = null; } }
/// <summary> /// Calls the service. /// </summary> /// <param name="reqMsg">The MSG.</param> /// <returns>The result.</returns> public override ResponseMessage CallService(RequestMessage reqMsg) { //如果已经是Invoke调用,则直接返回 if (reqMsg.InvokeMethod) { return base.CallService(reqMsg); } else { var method = GetInvokeMethod(reqMsg); //处理开始 HandleBegin(reqMsg, method); //调用服务 var resMsg = base.CallService(reqMsg); //处理结束 HandleEnd(resMsg, method); return resMsg; } }
/// <summary> /// 获取AppCaller /// </summary> /// <param name="client"></param> /// <param name="reqMsg"></param> /// <returns></returns> private AppCaller CreateCaller(IScsServerClient client, RequestMessage reqMsg) { //获取AppPath var appPath = (client.State == null) ? null : (client.State as AppClient).AppPath; //服务参数信息 var caller = new AppCaller { AppPath = appPath, AppName = reqMsg.AppName, IPAddress = reqMsg.IPAddress, HostName = reqMsg.HostName, ServiceName = reqMsg.ServiceName, MethodName = reqMsg.MethodName, Parameters = reqMsg.Parameters.ToString(), CallTime = DateTime.Now }; return caller; }
/// <summary> /// 创建服务 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> private IService CreateService(RequestMessage reqMsg) { //等待超时 var timeSpan = TimeSpan.FromSeconds(status.Config.Timeout); if (callTimeouts.ContainsKey(reqMsg.ServiceName)) { timeSpan = TimeSpan.FromSeconds(callTimeouts[reqMsg.ServiceName]); } //解析服务 var service = ParseService(reqMsg); return new AsyncService(smart, status.Container, service, timeSpan); }
/// <summary> /// 获取异常 /// </summary> /// <param name="context"></param> /// <param name="reqMsg"></param> /// <param name="exception"></param> /// <returns></returns> private static IoCException GetException(OperationContext context, RequestMessage reqMsg, IoCException exception) { exception.ApplicationName = reqMsg.AppName; exception.ServiceName = reqMsg.ServiceName; exception.ErrorHeader = string.Format("App【{0}】occurs error, comes from {1}({2}).", reqMsg.AppName, reqMsg.HostName, reqMsg.IPAddress); //上下文不为null if (context != null && context.Caller != null) { var caller = context.Caller; if (!string.IsNullOrEmpty(caller.AppPath)) { exception.ErrorHeader = string.Format("{0}\r\nApplication Path: {1}", exception.ErrorHeader, caller.AppPath); } } return exception; }
/// <summary> /// 获取IoCException /// </summary> /// <param name="context"></param> /// <param name="reqMsg"></param> /// <param name="message"></param> /// <param name="inner"></param> /// <returns></returns> public static IoCException GetException(OperationContext context, RequestMessage reqMsg, string message, Exception inner) { var exception = new IoCException(message, inner); //获取IoC异常 return GetException(context, reqMsg, exception); }
/// <summary> /// 获取IoCException /// </summary> /// <param name="context"></param> /// <param name="reqMsg"></param> /// <param name="message"></param> /// <returns></returns> public static IoCException GetException(OperationContext context, RequestMessage reqMsg, string message) { var exception = new WarningException(message); //获取警告异常 return GetException(context, reqMsg, exception); }
/// <summary> /// 实例化QueueResult /// </summary> /// <param name="reqMsg"></param> public WaitResult(RequestMessage reqMsg) { this.reset = new AutoResetEvent(false); }
/// <summary> /// 实例化AsyncResult /// </summary> /// <param name="context"></param> /// <param name="reqMsg"></param> public AsyncResult(OperationContext context, RequestMessage reqMsg) { this.reset = new AutoResetEvent(false); this.context = context; this.request = reqMsg; }
/// <summary> /// Calls the service. /// </summary> /// <param name="reqMsg">Name of the sub service.</param> /// <returns>The result.</returns> protected virtual ResponseMessage CallService(RequestMessage reqMsg) { ResponseMessage resMsg = null; try { //写日志开始 logger.BeginRequest(reqMsg); //开始计时 var watch = Stopwatch.StartNew(); //调用服务 resMsg = service.CallService(reqMsg); watch.Stop(); //写日志结束 logger.EndRequest(reqMsg, resMsg, watch.ElapsedMilliseconds); //如果有异常,向外抛出 if (resMsg.IsError) throw resMsg.Error; } catch (BusinessException ex) { throw ex; } catch (Exception ex) { if (config.ThrowError) throw ex; else container.Write(ex); } return resMsg; }
/// <summary> /// 调用方法返回 /// </summary> /// <param name="method"></param> /// <param name="collection"></param> /// <returns></returns> private ResponseMessage InvokeMethod(System.Reflection.MethodInfo method, ParameterCollection collection) { #region 设置请求信息 var reqMsg = new RequestMessage { AppName = config.AppName, //应用名称 HostName = hostName, //客户端名称 IPAddress = ipAddress, //客户端IP地址 ReturnType = method.ReturnType, //返回类型 ServiceName = serviceType.FullName, //服务名称 MethodName = method.ToString(), //方法名称 TransactionId = Guid.NewGuid(), //传输ID号 MethodInfo = method, //设置调用方法 Parameters = collection //设置参数 }; #endregion //调用服务 return CallService(reqMsg); }
/// <summary> /// 发送数据包 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> public void SendMessage(RequestMessage reqMsg) { this.request = reqMsg; //如果未连接上服务 if (!IsConnected) ConnectServer(reqMsg); client.SendMessage(new ScsResultMessage(reqMsg, reqMsg.TransactionId.ToString())); }
/// <summary> /// Runs the specified MSG. /// </summary> /// <param name="reqMsg">The MSG.</param> /// <returns>The msg.</returns> protected abstract ResponseMessage Run(RequestMessage reqMsg);
/// <summary> /// Gets the service. /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> private IService ParseService(RequestMessage reqMsg) { IService service = null; string serviceKey = "Service_" + reqMsg.ServiceName; if (status.Container.Kernel.HasComponent(serviceKey)) { service = status.Container.Resolve<IService>(serviceKey); } if (service == null) { string body = string.Format("The server【{1}({2})】not find matching service ({0})." , reqMsg.ServiceName, DnsHelper.GetHostName(), DnsHelper.GetIPAddress()); //获取异常 throw IoCHelper.GetException(OperationContext.Current, reqMsg, body); } return service; }
/// <summary> /// 调用服务 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> public ResponseMessage CallService(RequestMessage reqMsg) { IList<IService> proxies = new List<IService>(); //判断是否为StatusService服务 if (reqMsg.ServiceName == typeof(IStatusService).FullName) { throw new WarningException("Status service can't use discover service way!"); } //如果能找到服务 if (services.ContainsKey(reqMsg.ServiceName)) { proxies = services[reqMsg.ServiceName]; } else { //找到代理服务 lock (services) { //代理数为1时,直接处理 if (factory.Proxies.Count == 1) { proxies.Add(factory.Proxies[0]); services[reqMsg.ServiceName] = proxies; } else { foreach (var proxy in factory.Proxies) { try { //自定义实现一个ServerNode var node = new ServerNode { IP = proxy.Node.IP, Port = proxy.Node.Port, Compress = proxy.Node.Compress, Encrypt = proxy.Node.Encrypt, Key = Guid.NewGuid().ToString(), MaxPool = 1, Timeout = 30 }; var service = factory.GetChannel<IStatusService>(node); //检测是否存在服务 if (service.ContainsService(reqMsg.ServiceName)) { proxies.Add(proxy); } } catch (WarningException ex) { throw ex; } } } //缓存代理服务 if (proxies.Count > 0) services[reqMsg.ServiceName] = proxies; else throw new WarningException(string.Format("Did not find the proxy service {0}!", reqMsg.ServiceName)); } } //随机获取一个代理,实现分布式处理 var rndIndex = new Random(Guid.NewGuid().GetHashCode()).Next(proxies.Count); return proxies[rndIndex].CallService(reqMsg); }
/// <summary> /// 调用方法 /// </summary> /// <param name="reqMsg"></param> /// <returns></returns> public virtual ResponseMessage CallService(RequestMessage reqMsg) { //获取一个请求 ServiceRequest reqProxy = null; try { //处理数据 using (var waitResult = new WaitResult(reqMsg)) { hashtable[reqMsg.TransactionId] = waitResult; //获取一个请求 reqProxy = GetRequest(); //发送消息 reqProxy.SendMessage(reqMsg); //等待信号响应 var elapsedTime = TimeSpan.FromSeconds(node.Timeout); if (!waitResult.Wait(elapsedTime)) { //如果请求超时,则断开连接 reqProxy.Disconnect(); throw new WarningException(string.Format("【{0}:{1}】 => Call service ({2}, {3}) timeout ({4}) ms.\r\nParameters => {5}" , node.IP, node.Port, reqMsg.ServiceName, reqMsg.MethodName, (int)elapsedTime.TotalMilliseconds, reqMsg.Parameters.ToString())); } return waitResult.Message; } } finally { //加入队列 if (reqProxy != null) { reqPool.Push(reqProxy); } //用完后移除 hashtable.Remove(reqMsg.TransactionId); } }
/// <summary> /// 清理资源 /// </summary> public void Dispose() { this.reset.Reset(); this.thread = null; this.reset = null; this.request = null; this.message = null; this.context = null; //上下文设置为null OperationContext.Current = null; }
/// <summary> /// 连接服务器 /// </summary> private void ConnectServer(RequestMessage reqMsg) { //如果连接断开,直接抛出异常 if (!IsConnected) { try { //连接到服务器 client.Connect(); //发送客户端信息到服务端 var clientInfo = new AppClient { AppPath = AppDomain.CurrentDomain.BaseDirectory, AppName = reqMsg.AppName, IPAddress = reqMsg.IPAddress, HostName = reqMsg.HostName }; client.SendMessage(new ScsClientMessage(clientInfo)); } catch (Exception e) { throw new WarningException(string.Format("Can't connect to server ({0}:{1})!Server node : {2} -> {3}", ip, port, node, e.Message)); } } }
/// <summary> /// Runs the specified MSG. /// </summary> /// <param name="reqMsg">The MSG.</param> /// <returns>The msg.</returns> protected override ResponseMessage Run(RequestMessage reqMsg) { var resMsg = new ResponseMessage { TransactionId = reqMsg.TransactionId, ReturnType = reqMsg.ReturnType, ServiceName = reqMsg.ServiceName, MethodName = reqMsg.MethodName }; #region 获取相应的方法 var methodKey = string.Format("{0}${1}", reqMsg.ServiceName, reqMsg.MethodName); if (!hashtable.ContainsKey(methodKey)) { var m = CoreHelper.GetMethodFromType(serviceType, reqMsg.MethodName); if (m == null) { string message = string.Format("The server【{2}({3})】not find matching method. ({0},{1})." , reqMsg.ServiceName, reqMsg.MethodName, DnsHelper.GetHostName(), DnsHelper.GetIPAddress()); resMsg.Error = new WarningException(message); return resMsg; } hashtable[methodKey] = m; } #endregion //容器实例对象 object instance = null; try { //定义Method var method = hashtable[methodKey] as System.Reflection.MethodInfo; //解析服务 instance = container.Resolve(serviceType); //返回拦截服务 var service = AspectFactory.CreateProxyService(serviceType, instance); if (reqMsg.InvokeMethod) { var objValue = reqMsg.Parameters["InvokeParameter"]; var jsonString = (objValue == null ? string.Empty : objValue.ToString()); //解析参数 reqMsg.Parameters = IoCHelper.CreateParameters(method, jsonString); } //参数赋值 object[] parameters = IoCHelper.CreateParameterValues(method, reqMsg.Parameters); //调用对应的服务 resMsg.Value = DynamicCalls.GetMethodInvoker(method).Invoke(service, parameters); //处理返回参数 IoCHelper.SetRefParameters(method, resMsg.Parameters, parameters); //返回结果数据 if (reqMsg.InvokeMethod) { resMsg.Value = new InvokeData { Value = SerializationManager.SerializeJson(resMsg.Value), Count = resMsg.Count, OutParameters = resMsg.Parameters.ToString() }; //清除参数集合 resMsg.Parameters.Clear(); } } catch (Exception ex) { //捕获全局错误 resMsg.Error = ex; } finally { //释放资源 container.Release(instance); instance = null; } return resMsg; }