Beispiel #1
0
        /// <summary>
        /// Run the worker process. Creates a connection to the RabbitMQ broker and processes the received messaged.
        /// </summary>
        /// <param name="autoResetEvent">Reset event to signals the method to exit.</param>
        /// <exception cref="InvalidOperationException">Thrown if the RabbitMQ connection cannot be resolved.</exception>
        public void Run(AutoResetEvent autoResetEvent)
        {
            IConnection connection = ServiceProvider.GetService(typeof(IConnection)) as IConnection;

            if (connection == null)
            {
                throw new InvalidOperationException("RabbitMQ IConnection service not configured");
            }

            using (var channel = connection.CreateModel())
            {
                ChannelHelper.EnsureQueue(ActionCode, channel);
                channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: true);

                var consumer = new EventingBasicConsumer(channel);

                consumer.Received += (model, ea) =>
                {
                    var props      = ea.BasicProperties;
                    var replyProps = channel.CreateBasicProperties();

                    RequestMessage  request  = SerializationHelper.FromBytes <RequestMessage>(ea.Body);
                    ResponseMessage response = null;

                    replyProps.CorrelationId = props.CorrelationId;

                    try
                    {
                        XElement data = Process(request);
                        response = ResponseMessage.CreateResponseOK(data);
                    }
                    catch (Exception ex)
                    {
                        response = ResponseMessage.CreateResponseERROR(ex);
                    }
                    finally
                    {
                        if (response != null)
                        {
                            var responseBytes = SerializationHelper.ToBytes(response);
                            channel.BasicPublish(exchange: "",
                                                 routingKey: props.ReplyTo,
                                                 basicProperties: replyProps,
                                                 body: responseBytes);
                        }

                        channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                    }
                };

                channel.BasicConsume(queue: ActionCode,
                                     autoAck: false,
                                     consumer: consumer);

                autoResetEvent.WaitOne();
            }
        }
Beispiel #2
0
        public RpcClient(IConnection rmqConnection)
        {
            clientID    = Guid.NewGuid().ToString("N");
            actionCodes = new List <string>();
            tasksDict   = new ConcurrentDictionary <string, TaskCompletionSource <ResponseMessage> >();

            connection = rmqConnection;

            channel = connection.CreateModel();
            ChannelHelper.EnsureQueue(ReplyQueueName, channel, true);
            consumer           = new EventingBasicConsumer(channel);
            consumer.Received += Consumer_Received;

            channel.BasicConsume(queue: ReplyQueueName,
                                 autoAck: true,
                                 consumer: consumer);
        }
Beispiel #3
0
        /// <summary>
        /// Publish message to the message broker.
        /// </summary>
        /// <param name="request">Request object instance.</param>
        /// <param name="secondsTimeout">Number of seconds to wait for action completion.</param>
        /// <returns>Response generated from remote action execution.</returns>
        /// <exception cref="TimeoutException">Exception raised when the action does not completes before the timeout period.</exception>
        public Task <ResponseMessage> Execute(RequestMessage request, int secondsTimeout = 15)
        {
            var correlationId    = Guid.NewGuid().ToString("N");
            var completionSource = tasksDict.GetOrAdd(correlationId, new TaskCompletionSource <ResponseMessage>());

            var bytes = SerializationHelper.ToBytes(request);
            var props = channel.CreateBasicProperties();

            props.DeliveryMode  = 2;
            props.CorrelationId = correlationId;
            props.ReplyTo       = ReplyQueueName;

            if (!actionCodes.Contains(request.ActionCode))
            {
                ChannelHelper.EnsureQueue(request.ActionCode, channel);
                actionCodes.Add(request.ActionCode);
            }

            channel.BasicPublish(
                exchange: "",
                routingKey: request.ActionCode,
                basicProperties: props,
                body: bytes);

            Task.WhenAny(completionSource.Task, Task.Delay(secondsTimeout * 1000)).ContinueWith(t =>
            {
                if (!completionSource.Task.IsCompleted)
                {
                    if (tasksDict.TryRemove(correlationId, out TaskCompletionSource <ResponseMessage> source))
                    {
                        source.SetException(new TimeoutException());
                    }
                }
            });

            return(completionSource.Task);
        }