/// <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); }
/* * /// <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); }
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; }
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); }