예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        /// <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);
        }
예제 #5
0
        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;
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        /// <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;
        }
예제 #9
0
        /// <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;
                }
            }
        }
예제 #10
0
        /// <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;
            }
        }
예제 #11
0
        /// <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;
            }
        }
예제 #12
0
        /// <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;
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        /// <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;
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
 /// <summary>
 /// 实例化QueueResult
 /// </summary>
 /// <param name="reqMsg"></param>
 public WaitResult(RequestMessage reqMsg)
 {
     this.reset = new AutoResetEvent(false);
 }
예제 #18
0
 /// <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);
        }
예제 #21
0
        /// <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()));
        }
예제 #22
0
 /// <summary>
 /// Runs the specified MSG.
 /// </summary>
 /// <param name="reqMsg">The MSG.</param>
 /// <returns>The msg.</returns>
 protected abstract ResponseMessage Run(RequestMessage reqMsg);
예제 #23
0
        /// <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;
        }
예제 #24
0
        /// <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);
        }
예제 #25
0
        /// <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);
            }
        }
예제 #26
0
        /// <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;
        }
예제 #27
0
        /// <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));
                }
            }
        }
예제 #28
0
        /// <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;
        }