Esempio n. 1
0
        /// <summary>
        /// 触发命令且无返回值
        /// </summary>
        /// <typeparam name="TServiceCommand">命令定义</typeparam>
        /// <param name="commandData">命令实例</param>
        /// <param name="exceptionHandler">异常处理</param>
        public EmptyCommandResult TriggerServiceCommand <TServiceCommand>(
            TServiceCommand commandData, Action <Exception> exceptionHandler = null)
            where TServiceCommand : IServiceCommand <EmptyCommandResult>
        {
            RemoteServiceBusResponseContext remoteContext = null;

            return(this.TriggerServiceCommand <TServiceCommand>(commandData, exceptionHandler, out remoteContext));
        }
        private bool dispatchCommand(
            ServiceUniqueNameInfo commandUniqueName, IRpcMessageSenderContext context, string requestMessageContent,
            out RemoteServiceBusResponseContext responseContext, out string responseMessageContent, out WindServiceBusRpcException rpcException)
        {
            // 创建响应上下文
            responseMessageContent = null;
            rpcException           = null;
            responseContext        = new RemoteServiceBusResponseContext();
            context.FillRemoteContext(responseContext);

            // 通过RPC框架执行远程调用
            try
            {
                RpcTransportMessageRequest requestMessage = new RpcTransportMessageRequest(MessageIdGenerator.CreateMessageId())
                {
                    ServiceUniqueName = commandUniqueName,
                    MessageHeader     = new RpcTransportMessageHeader
                    {
                        //TODO: 其他消息头
                    },
                    MessageContent = requestMessageContent,
                };
                RpcTransportMessageResponse responseMessage = this.rpcServerManager.SendMessage(requestMessage, context);

                //响应上下文
                if (responseMessage != null)
                {
                    responseContext.FillRemoteContext(responseMessage.MessageHeader);   //服务响应信息填入RemoteContext
                }

                //响应消息验证
                if (responseMessage == null || responseMessage.CorrelationMessageId == null ||
                    responseMessage.CorrelationMessageId != requestMessage.MessageId ||
                    responseMessage.MessageContent == null)
                {
                    throw new WindServiceBusException(string.Format("request [{0}] get error response !", requestMessage.MessageId));
                }

                if (responseMessage.ResponseCode != RpcTransportResponseCode.Success)
                {
                    throw new WindServiceBusException(string.Format("request [{0}] get error response: {1}", requestMessage.MessageId, responseMessage.ErrorInfo));
                }

                responseMessageContent = responseMessage.MessageContent;
                return(true);    //请求成功
            }
            catch (Exception serviceBusException)
            {
                this._logger.Error("WindServiceBusException: " + commandUniqueName, serviceBusException);
                rpcException = new WindServiceBusRpcException(responseContext, serviceBusException);

                return(false);   //请求失败
            }
        }
Esempio n. 3
0
 /// <summary>
 /// 触发命令且无返回值
 /// </summary>
 /// <typeparam name="TServiceCommand">命令定义</typeparam>
 /// <param name="commandData">命令实例</param>
 /// <param name="exceptionHandler">异常处理</param>
 /// <param name="remoteContext">远程上下文(如果为本地调用,则返回null)</param>
 public EmptyCommandResult TriggerServiceCommand <TServiceCommand>(
     TServiceCommand commandData, Action <Exception> exceptionHandler, out RemoteServiceBusResponseContext remoteContext)
     where TServiceCommand : IServiceCommand <EmptyCommandResult>
 {
     remoteContext = null;
     try
     {
         var cmdResult = this.TriggerServiceCommandCore(
             typeof(TServiceCommand), typeof(EmptyCommandResult), commandData, out remoteContext);
         return((EmptyCommandResult)cmdResult);
     }
     catch (Exception ex)
     {
         if (exceptionHandler != null)
         {
             exceptionHandler(ex);
         }
     }
     return(null);
 }
        internal ServiceResponseMessageWithResponseContext DispatchCommand(ServiceUniqueNameInfo commandUniqueName, string requestMessageContent)
        {
            //1. 服务发现(找到所有可以请求的目标)
            var remoteContextList = this.rpcServerManager.DiscoverRemoteService(commandUniqueName);

            if (remoteContextList == null || remoteContextList.Count < 1)
            {
                throw new WindServiceBusRemoteServiceNotFoundException(commandUniqueName.FullServiceUniqueName);
            }

            //2. 依次尝试发现的目标服务程序集
            bool isDispatchSuccess = false;
            RemoteServiceBusResponseContext responseContext = null;
            string responseMessageContent = null;
            List <WindServiceBusRpcException> servicebusExceptionCollection = new List <WindServiceBusRpcException>();

            var contextQueue = new Queue <IRpcMessageSenderContext>(remoteContextList);

            while (!isDispatchSuccess && contextQueue.Count > 0)
            {
                var context = contextQueue.Dequeue();

                WindServiceBusRpcException busException;
                isDispatchSuccess = this.dispatchCommand(commandUniqueName, context, requestMessageContent,
                                                         out responseContext, out responseMessageContent, out busException);

                if (!isDispatchSuccess && busException != null)
                {
                    servicebusExceptionCollection.Add(busException);
                }
            }

            if (!isDispatchSuccess)
            {
                throw new WindServiceBusMultiRpcException(servicebusExceptionCollection);
            }

            return(new ServiceResponseMessageWithResponseContext(responseMessageContent, responseContext));
        }
Esempio n. 5
0
 public void FillRemoteContext(RemoteServiceBusResponseContext remoteContext)
 {
     remoteContext["TargetAppClassId"] = this.TargetAppClassId.ToString();
     remoteContext["TargetCommandId"]  = this.TargetCommandId.ToString();
     remoteContext["CommandTimeout"]   = this.CommandTimeout.ToString();
 }
Esempio n. 6
0
 public WindServiceBusRpcException(RemoteServiceBusResponseContext remoteContext, Exception innerException)
     : base(innerException.Message, innerException)
 {
     this.RemoteContext = remoteContext;
 }
Esempio n. 7
0
        /*
         * /// <summary>
         * /// 调用本地服务命令
         * /// </summary>
         * /// <param name="commandType">命令类型</param>
         * /// <param name="commandResultType">命令响应类型</param>
         * /// <param name="commandData">命令实例</param>
         * /// <returns>是否执行成功</returns>
         * private bool TriggerServiceCommandLocal(
         *  Type commandType, Type commandResultType, IServiceCommand commandData,
         *  out ServiceCommandResultWithResponseContext commandResultData)
         * {
         *  //TODO: 创建服务响应环境的上下文信息
         *  IServiceBusResponseContext responseContext = new BasicServiceBusResponseContext();
         *
         *  //从本地容器找
         *  IServiceCommandHandlerFactory handlerFactory = null;
         *  bool isLocalExists = this._commandHandlerFactories.TryGetValue(commandType, out handlerFactory);
         *  if (isLocalExists)
         *  {
         *      responseContext.IsFromLocalService = true;
         *      IServiceCommandHandler commandHandler = handlerFactory.CreateHandler(); //服务实例(消费者)
         *
         *      try
         *      {
         *          Type commandHandlerType = typeof(IServiceCommandHandler<,>).MakeGenericType(commandType, commandResultType);
         *          MethodInfo method = commandHandlerType.GetMethod("HandlerCommand", new[] { commandType });
         *          var result = (IServiceCommandResult)method.Invoke(commandHandler, new object[] { commandData });
         *          result.CommandId = commandData.CommandId;    //设置命令ID
         *
         *          commandResultData = new ServiceCommandResultWithResponseContext(result, responseContext);
         *          return true;
         *      }
         *      catch (Exception ex)
         *      {
         *          //TODO: 异常处理
         *          throw ex;
         *      }
         *      finally
         *      {
         *          //清理服务
         *          handlerFactory.ReleaseHandler(commandHandler);
         *      }
         *  }
         *  commandResultData = null;
         *  return false;   //本地调用失败
         * }
         */

        /*
         * /// <summary>
         * /// 调用远程服务命令
         * /// </summary>
         * /// <param name="serviceName">服务名称</param>
         * /// <param name="commandType">命令类型</param>
         * /// <param name="commandResultType">命令响应类型</param>
         * /// <param name="commandData">命令实例</param>
         * /// <returns>命令响应实例及响应上下文</returns>
         * private ServiceCommandResultWithResponseContext TriggerServiceCommandRemote(
         *  string serviceName, Type commandType, Type commandResultType, IServiceCommand commandData)
         * {
         *  //TODO: 创建服务响应环境的上下文信息
         *  IServiceBusResponseContext responseContext = new RemoteServiceBusResponseContext();
         *
         *  //1. TODO: 处理请求消息体
         *  byte[] requestMessageContent = null;
         *  try
         *  {
         *      requestMessageContent = this.Serializer.Serialize(commandData).ToBytes();
         *  }
         *  catch (Exception ex)
         *  {
         *      //TODO: 消息内容序列化失败
         *      throw new WindServiceBusException("Serialize command data failed !", ex);
         *  }
         *
         *  //2. 通过RPC框架执行远程调用
         *  byte[] responseMessageContent = null;
         *  try
         *  {
         *      var rpcServerManager = this.IocResolver.Resolve<RpcServerManager>();
         *      RpcTransportMessage requestMessage = new RpcTransportMessage(commandData.CommandId)
         *      {
         *          MessageType = commandType.FullName,
         *          MessageContent = requestMessageContent,
         *      };
         *      RpcTransportMessage responseMessage = rpcServerManager.SendMessage(serviceName, requestMessage);
         *
         *      //响应消息验证
         *      if (responseMessage == null || responseMessage.CorrelationMessageId == null
         || responseMessage.CorrelationMessageId != requestMessage.MessageId
         || responseMessage.MessageContent == null)
         ||     {
         ||         throw new WindServiceBusException(string.Format("request [{0}] get error response !", requestMessage.MessageId));
         ||     }
         ||     responseMessageContent = responseMessage.MessageContent;
         || }
         || catch (WindServiceBusServiceNotFoundException notFoundEx)
         || {
         ||     //TODO: 未找到符合的远程服务
         ||     throw notFoundEx;
         || }
         || catch (Exception ex)
         || {
         ||     //TODO: 其他异常处理
         ||     throw ex;
         || }
         ||
         || //3. 处理响应消息体
         || IServiceCommandResult commandResult = null;
         || using (var responseStream = new MemoryStream(responseMessageContent))
         || {
         ||     var obj = this.Serializer.Deserialize(commandResultType, responseStream);
         ||     commandResult = (IServiceCommandResult)obj;
         || }
         ||
         || return new ServiceCommandResultWithResponseContext(commandResult, responseContext);
         ||}
         */

        /// <summary>
        /// 执行命令服务核心
        /// </summary>
        /// <typeparam name="TServiceCommand">命令服务类型</typeparam>
        /// <typeparam name="TCommandResult">命令服务返回结果类型</typeparam>
        /// <param name="commandData">命令服务数据</param>
        /// <param name="remoteContext">远端上下文(如果是本地调用,返回null)</param>
        /// <returns>命令服务返回结果数据</returns>
        internal IServiceCommandResult TriggerServiceCommandCore(Type commandType, Type commandResultType,
                                                                 IServiceCommand commandData, out RemoteServiceBusResponseContext remoteContext)
        {
            using (PerformanceCounter.BeginStopwatch(string.Format("localCall: {0}", commandType.FullName)))
            {
                //1. 本地调用
                IServiceCommandResult commandResult = null;
                bool isTriggeredLocal = this.triggerLocalCommand(commandType, commandResultType, commandData, out commandResult);
                if (isTriggeredLocal)
                {
                    remoteContext = null;
                    return(commandResult);
                }
            }

            //2. 从远程容器找
            try
            {
                using (PerformanceCounter.BeginStopwatch(string.Format("remoteCall: {0}", commandType.FullName)))
                {
                    var resultWithContext = this.triggerRemoteCommand(commandType, commandResultType, commandData);

                    remoteContext = resultWithContext.ResponseContext;
                    return(resultWithContext.ServiceCommandResult);
                }
            }
            catch (WindServiceBusRpcException rpcException)
            {
                remoteContext = rpcException.RemoteContext;
                throw rpcException.InnerException;
            }
            catch (WindServiceBusMultiRpcException multiRpcException)
            {
                //处理多次调度异常信息
                if (multiRpcException.Count == 1)
                {
                    var rpcException = multiRpcException.First();
                    remoteContext = rpcException.RemoteContext;
                    throw rpcException.InnerException;
                }
                else
                {
                    throw multiRpcException;
                }
            }
        }