/// <summary> /// Creates a RpcClient for each configured queue defined by other applications /// servers to which messages can be published and a response is expected. The /// external RPC queues exposed by other applications are specified within the /// configuration file. /// </summary> /// <param name="brokerName">The optional broker name to create RPC client for.</param> public void DeclareRpcClients(string brokerName = null) { IEnumerable <BrokerConnectionSettings> brokerConnections = _brokerState.BrokerSettings.Connections; // The broker name will be null when all the RPC response queues need to be re-created after // a connection exception is detected. if (brokerName != null) { brokerConnections = brokerConnections.Where(c => c.BrokerName == brokerName); } foreach (BrokerConnectionSettings brokerConn in brokerConnections) { foreach (RpcConsumerSettings rpcConsumer in brokerConn.RpcConsumers) { // The channel to await for replays to published messages. IModel replyChannel = _connMgr.CreateChannel(brokerConn.BrokerName); var rpcClient = new RpcClient(brokerConn.BrokerName, rpcConsumer, replyChannel); var rpcPublisher = new RpcMessagePublisher(brokerConn.BrokerName, rpcConsumer, rpcClient); _rpcMessagePublishers.Add(rpcPublisher); } } }
private void LogReceivedRpcResponse(IMessage message, RpcMessagePublisher rpcPublisher) { _logger.LogTraceDetails(RabbitMqLogEvents.PUBLISHER_RPC_RESPONSE, "RPC Reply Message Received", new { Message = message, rpcPublisher.BrokerName, rpcPublisher.RequestQueueName, rpcPublisher.Client.ReplyQueueName }); }
private RpcMessagePublisher GetRpcPublisher(RpcCommandAttribute consumerAttrib) { RpcMessagePublisher rpcPublisher = _rpcMessagePublishers.FirstOrDefault(c => c.BrokerName == consumerAttrib.BrokerName && c.RequestQueueKey == consumerAttrib.RequestQueueKey); if (rpcPublisher == null) { throw new BrokerException( $"RPC Publisher Client could not configured for Broker: {consumerAttrib.BrokerName} " + $"RequestQuoteKey: {consumerAttrib.RequestQueueKey}."); } return(rpcPublisher); }
private void LogPublishedRpcMessage(IMessage message, RpcMessagePublisher rpcPublisher, RpcProperties rpcProps) { _logger.LogTraceDetails(RabbitMqLogEvents.PUBLISHER_RPC_REQUEST, "Publishing to RPC Consumer", new { Message = message, rpcPublisher.BrokerName, rpcPublisher.RequestQueueKey, rpcPublisher.RequestQueueName, rpcPublisher.Client.ReplyQueueName, rpcProps.ContentType, rpcProps.ExternalTypeName }); }
/// <summary> /// Publishes a message to a consumer defined queue used for receiving /// RPC style messages. The caller awaits the reply response message. /// </summary> /// <param name="message">The RPC style message to publish.</param> /// <returns>Future result after the reply is received.</returns> public async Task PublishToRpcConsumerAsync(IMessage message, CancellationToken cancellationToken) { Check.NotNull(message, nameof(message)); AssertRpcCommand(message); var rpcCommandAttrib = message.GetAttribute <RpcCommandAttribute>(); var command = message as ICommand; RpcProperties rpcProps = new RpcProperties { ContentType = rpcCommandAttrib.ContentType, ExternalTypeName = rpcCommandAttrib.ExternalTypeName }; // Obtain the consumer queue on which the message should be published. RpcMessagePublisher rpcPublisher = GetRpcPublisher(rpcCommandAttrib); string[] orderedContentTypes = { message.GetContentType(), rpcProps.ContentType, rpcPublisher.ContentType }; byte[] messageBody = _serializationMgr.Serialize(command, orderedContentTypes); LogPublishedRpcMessage(message, rpcPublisher, rpcProps); // Publish the RPC request the consumer's queue and await a response. rpcProps.ContentType = command.GetContentType(); byte[] replyBody = null; try { replyBody = await rpcPublisher.Client.Invoke(command, rpcProps, cancellationToken, messageBody); object reply = _serializationMgr.Deserialize(rpcProps.ContentType, command.ResultType, replyBody); command.SetResult(reply); LogReceivedRpcResponse(message, rpcPublisher); } catch (RpcReplyException ex) { var dispatchEx = _serializationMgr.Deserialize <MessageDispatchException>(rpcProps.ContentType, ex.Exception); _logger.LogError(RabbitMqLogEvents.PUBLISHER_RPC_RESPONSE, "RPC Exception Reply.", dispatchEx); throw dispatchEx; } }