/// <summary>
        /// 响应远程请求
        /// </summary>
        public RpcTransportMessageResponse ProcessCommand(RpcTransportMessageRequest rpcRequest /*TODO: 请求上下文信息*/)
        {
            //本地服务发现
            ServiceCommandTypeInfo localCommandInfo = null;
            bool isLocalCommand = this.serviceBusRegistry.IsLocalServiceCommand(rpcRequest.ServiceUniqueName, out localCommandInfo);

            string responseMessageContent = null;

            if (isLocalCommand)
            {
                using (performanceCounter.BeginStopwatch(string.Format("localInvoke: {0}", rpcRequest.ServiceUniqueName.FullServiceUniqueName)))
                {
                    //本地服务
                    IServiceCommandResult commandResult = null;
                    var  commandData    = (IServiceCommand)this.serializer.DeserializeString(localCommandInfo.CommandType, rpcRequest.MessageContent);
                    bool triggeredLocal = serviceBus.triggerLocalCommand(localCommandInfo.CommandType, localCommandInfo.CommandResultType, commandData, out commandResult);
                    if (!triggeredLocal)
                    {
                        throw new WindServiceBusLocalServiceNotFoundException(rpcRequest.ServiceUniqueName.FullServiceUniqueName);
                    }

                    // 去除null判断,允许数据内容为null
                    //if (commandResult == null)
                    //{
                    //    throw new WindServiceBusException(string.Format("service command [{0}] process error!", rpcRequest.ServiceUniqueName.FullServiceUniqueName));
                    //}

                    responseMessageContent = this.serializer.SerializeString(commandResult);
                }
            }
            else
            {
                using (performanceCounter.BeginStopwatch(string.Format("remoteInvoke: {0}", rpcRequest.ServiceUniqueName.FullServiceUniqueName)))
                {
                    //远程服务
                    var resultWithContext = serviceBus.triggerRemoteCommand(rpcRequest.ServiceUniqueName, rpcRequest.MessageContent);
                    responseMessageContent = resultWithContext.ResponseMessageContent;
                }
            }

            //构建响应输出
            var messageHeader = new RpcTransportMessageHeader();
            var rpcResponse   = new RpcTransportMessageResponse(MessageIdGenerator.CreateMessageId())
            {
                MessageHeader        = messageHeader,
                CorrelationMessageId = rpcRequest.MessageId,
                ServiceUniqueName    = rpcRequest.ServiceUniqueName,
                MessageContent       = responseMessageContent
            };

            return(rpcResponse);
        }
Beispiel #2
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;
                }
            }
        }
        /// <summary>
        /// 响应远程广播请求
        /// </summary>
        /// <param name="rpcRequest"></param>
        /// <returns></returns>
        public RpcTransportMessageResponse ProcessBroadcastCommand(RpcTransportMessageRequest rpcRequest)
        {
            List <string> resultList = new List <string>();

            //1. 本地调用
            using (performanceCounter.BeginStopwatch(string.Format("localBroadcastInvoke: {0}", rpcRequest.ServiceUniqueName.FullServiceUniqueName)))
            {
                ServiceCommandTypeInfo localCommandInfo = null;
                bool isLocalCommand = this.serviceBusRegistry.IsLocalServiceCommand(rpcRequest.ServiceUniqueName, out localCommandInfo);

                if (isLocalCommand)
                {
                    IServiceCommandResult commandResult = null;
                    var  commandData    = (IServiceCommand)this.serializer.DeserializeString(localCommandInfo.CommandType, rpcRequest.MessageContent);
                    bool triggeredLocal = serviceBus.triggerLocalCommand(localCommandInfo.CommandType, localCommandInfo.CommandResultType, commandData, out commandResult);

                    if (triggeredLocal)
                    {
                        string responseMessageContent = this.serializer.SerializeString(commandResult);
                        resultList.Add(responseMessageContent);
                    }
                }
            }

            using (performanceCounter.BeginStopwatch(string.Format("remoteBroadcastInvoke: {0}", rpcRequest.ServiceUniqueName.FullServiceUniqueName)))
            {
                //2. 远程调用
                var resultWithContext = serviceBus.broadcastRemoteCommand(rpcRequest.ServiceUniqueName, rpcRequest.MessageContent);
                resultList.AddRange(resultWithContext.Select(r => r.ResponseMessageContent));
            }

            //3. 构建响应输出
            var contentResult = this.serializer.CombineToArray(resultList);

            var messageHeader = new RpcTransportMessageHeader();
            var rpcResponse   = new RpcTransportMessageResponse(MessageIdGenerator.CreateMessageId())
            {
                MessageHeader        = messageHeader,
                CorrelationMessageId = rpcRequest.MessageId,
                ServiceUniqueName    = rpcRequest.ServiceUniqueName,
                MessageContent       = contentResult
            };

            return(rpcResponse);
        }
Beispiel #4
0
        internal IEnumerable <IServiceCommandResult> BroadcastServiceCommandCore(Type commandType, Type commandResultType, IServiceCommand commandData)
        {
            using (PerformanceCounter.BeginStopwatch(string.Format("localBroadcast: {0}", commandType.FullName)))
            {
                //1. 本地调用
                IServiceCommandResult commandResult = null;
                bool isTriggeredLocal = this.triggerLocalCommand(commandType, commandResultType, commandData, out commandResult);
                if (isTriggeredLocal)
                {
                    yield return(commandResult);
                }
            }

            using (PerformanceCounter.BeginStopwatch(string.Format("remoteBroadcast: {0}", commandType.FullName)))
            {
                //2. 远程调用
                var remoteCommandDispatcher = this.createRemoteDispatcher();
                var remoteResultList        = remoteCommandDispatcher.BroadcastCommand(commandType, commandResultType, commandData);
                foreach (var remoteResult in remoteResultList)
                {
                    yield return(remoteResult.ServiceCommandResult);
                }
            }
        }
 public ServiceCommandResultWithResponseContext(
     IServiceCommandResult result, RemoteServiceBusResponseContext context)
 {
     this.ServiceCommandResult = result;
     this.ResponseContext      = context;
 }
Beispiel #6
0
        internal bool triggerLocalCommand(Type commandType, Type commandResultType, IServiceCommand commandData, out IServiceCommandResult commandResult)
        {
            //命令参数验证规则
            if (commandData == null)
            {
                throw new WindServiceBusException("command data empty error!", new ArgumentNullException("commandData"));
            }

            //从本地容器调用
            var  registry       = this.IocResolver.Resolve <ServiceBusRegistry>();
            bool isLocalCommand = registry.IsLocalServiceCommand(new ServiceUniqueNameInfo(commandType));

            if (!isLocalCommand)
            {
                commandResult = null;
                return(false);
            }

            var localCommandDispatcher = this.createLocalDispatcher(registry);

            commandResult = localCommandDispatcher.DispatchCommand(commandType, commandResultType, commandData);
            return(true);
        }