/// <summary> /// 调用方法 /// </summary> /// <param name="args"></param> public void Call(CallEventArgs args) { //计数按方法 var thisKey = string.Format("{0}${1}${2}${3}", args.Caller.AppName, args.Caller.ServiceName, args.Caller.MethodName, args.Caller.Parameters); var callKey = IoCHelper.GetMD5String(thisKey); lock (hashtable.SyncRoot) { if (!hashtable.ContainsKey(callKey)) { var counterInfo = new CounterInfo { AppName = args.Caller.AppName, ServiceName = args.Caller.ServiceName, MethodName = args.Caller.MethodName, Parameters = args.Caller.Parameters, NeedReset = false, Count = 1 }; hashtable[callKey] = counterInfo; return; } } var counter = hashtable[callKey] as CounterInfo; if (counter.NeedReset) { //重置计数器 hashtable.Remove(callKey); //如果调用次数超过最大允许数,则提示警告 if (counter.Count >= maxCount) { var warning = new WarningException(string.Format("【{0}】 One minute call service ({1}, {2}) {3} times more than {4} times.\r\nParameters => {5}", counter.AppName, counter.ServiceName, counter.MethodName, counter.Count, maxCount, counter.Parameters)); //内部异常 var error = new IoCException(string.Format("【{0}】 One minute call service ({1}) {2} times.", counter.AppName, counter.ServiceName, counter.Count), warning); //抛出异常 args.Error = error; } } else { //计数器加1 counter.Count++; } }
/// <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="callArgs"></param> private void NotifyEventArgs(CallEventArgs callArgs) { //调用计数 ManagedThreadPool.QueueUserWorkItem(state => { try { var arr = state as ArrayList; var statusService = arr[0] as ServerStatusService; var eventArgs = arr[1] as CallEventArgs; //调用计数服务 statusService.Counter(eventArgs); //响应消息 MessageCenter.Instance.Notify(eventArgs); } catch (Exception ex) { //TODO } }, new ArrayList { status, callArgs }); }
/// <summary> /// 进行计数处理并响应 /// </summary> /// <param name="args"></param> internal void Counter(CallEventArgs args) { //获取或创建一个对象 var status = statuslist.GetOrCreate(args.Caller.CallTime); //处理时间 status.ElapsedTime += args.ElapsedTime; //错误及成功计数 if (args.IsError) status.ErrorCount++; else status.SuccessCount++; //计算统计 counterlist.Call(args); }
/// <summary> /// 调用事件信息 /// </summary> /// <param name="callArgs"></param> public void Notify(CallEventArgs callArgs) { if (_listeners.Count == 0) return; MessageListener[] listeners = _listeners.ToArray(); foreach (MessageListener lstn in listeners) { try { if ((lstn.Apps.Count == 0 || lstn.Apps.Any(p => string.Compare(p, callArgs.Caller.AppName, true) == 0)) && (lstn.Types.Count == 0 || lstn.Types.Any(p => string.Compare(p, callArgs.Caller.ServiceName, true) == 0))) { var options = lstn.Options; if (options.PushCallError && callArgs.IsError) { var callError = new CallError { Caller = callArgs.Caller, Message = callArgs.Error.Message, Error = ErrorHelper.GetErrorWithoutHtml(callArgs.Error), HtmlError = ErrorHelper.GetHtmlError(callArgs.Error) }; lstn.Notify(callError); } if (options.PushCallTimeout && !callArgs.IsError) { //如果设定的时间不正确,不进行推送 if (options.CallTimeout <= 0 && options.CallRowCount <= 0) continue; if (callArgs.ElapsedTime > options.CallTimeout * 1000 || callArgs.Count > options.CallRowCount) { var callTimeout = new CallTimeout { Caller = callArgs.Caller, Count = callArgs.Count, ElapsedTime = callArgs.ElapsedTime }; lstn.Notify(callTimeout); } } } } catch (SocketException ex) { RemoveListener(lstn); } catch (Exception ex) { if (OnError != null) OnError(ex); } } }