/// <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); //请求失败 } }
/// <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)); }
public void FillRemoteContext(RemoteServiceBusResponseContext remoteContext) { remoteContext["TargetAppClassId"] = this.TargetAppClassId.ToString(); remoteContext["TargetCommandId"] = this.TargetCommandId.ToString(); remoteContext["CommandTimeout"] = this.CommandTimeout.ToString(); }
public WindServiceBusRpcException(RemoteServiceBusResponseContext remoteContext, Exception innerException) : base(innerException.Message, innerException) { this.RemoteContext = remoteContext; }
/* * /// <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; } } }