예제 #1
0
 protected void EnsureQueueExists(QueueConfiguration config)
 {
     Channel.QueueDeclare(config.Name, config.Durable, config.Exclusive, config.AutoDelete);
     foreach (var exchange in config.Exchanges)
     {
         Channel.ExchangeDeclare(exchange.Name, exchange.Type, exchange.Durable, exchange.AutoDelete);
         Channel.QueueBind(config.Name, exchange.Name, config.BindingKey ?? config.Name);
     }
 }
예제 #2
0
        protected void Write <TMessage>(QueueConfiguration queue, TMessage value, string routingKey = null)
        {
            routingKey = routingKey ?? queue.Name;
            EnsureQueueExists(queue);
            var sendProps = Channel.CreateBasicProperties();

            sendProps.Persistent = true;
            var messageBody = MessageHandler.Encode(value);

            Channel.BasicPublish(Exchange.Name, routingKey, sendProps, messageBody);
        }
예제 #3
0
        protected Task <EventingBasicConsumer> ReadAndReply <TMessage, TResponse>(QueueConfiguration queue, bool autoAck, Func <object, ReceiveEventArgs <TMessage>, Task <TResponse> > handler)
        {
            EnsureQueueExists(queue);
            async void MessageHandlerAsync(object sender, BasicDeliverEventArgs args)
            {
                var props      = args.BasicProperties;
                var replyProps = Channel.CreateBasicProperties();

                replyProps.CorrelationId = props.CorrelationId;

                TMessage message      = MessageHandler.Decode <TMessage>(args.Body);
                var      receivedArgs = new ReceiveEventArgs <TMessage>(message, autoAck);

                try
                {
                    var result = await handler(sender, receivedArgs);

                    // If there's a queue to reply to.
                    if (!string.IsNullOrEmpty(props.ReplyTo))
                    {
                        var response = MessageHandler.Encode(result);
                        Channel.BasicPublish(args.Exchange, props.ReplyTo, replyProps, response);
                    }
                }
                catch (Exception ex)
                {
                    // Throw or return the error.
                    if (!string.IsNullOrEmpty(props.ReplyTo))
                    {
                        var response = MessageHandler.Encode(new ErrorMessage(ex));
                        replyProps.Type = nameof(Exception);
                        Channel.BasicPublish(args.Exchange, props.ReplyTo, replyProps, response);
                    }
                    throw;
                }
                finally
                {
                    if (receivedArgs.Acknowledge)
                    {
                        Channel.BasicAck(args.DeliveryTag, false);
                    }
                }
            }

            return(Task.FromResult(ConsumeQueue(queue.Name, MessageHandlerAsync)));
        }
예제 #4
0
        protected Task <EventingBasicConsumer> Read <TMessage>(QueueConfiguration queue, bool autoAck, Func <object, ReceiveEventArgs <TMessage>, Task> handler)
        {
            EnsureQueueExists(queue);
            async void MessageHandlerAsync(object sender, BasicDeliverEventArgs args)
            {
                TMessage message      = MessageHandler.Decode <TMessage>(args.Body);
                var      receivedArgs = new ReceiveEventArgs <TMessage>(message, autoAck);

                try
                {
                    await handler(sender, receivedArgs);
                }
                finally
                {
                    if (receivedArgs.Acknowledge)
                    {
                        Channel.BasicAck(args.DeliveryTag, false);
                    }
                }
            }

            return(Task.FromResult(ConsumeQueue(queue.Name, MessageHandlerAsync)));
        }
예제 #5
0
        protected async Task <MessageResponse <TResponse> > WriteAndReply <TMessage, TResponse>(QueueConfiguration queue, TMessage value, string routingKey = null, int millisecondsTimeout = -1, CancellationToken cancellationToken = default(CancellationToken))
        {
            routingKey = routingKey ?? queue.Name;
            EnsureQueueExists(queue);

            // Set up the queue that the reply will be written to.
            var replyQueue = Channel.QueueDeclare().QueueName;

            Channel.QueueBind(replyQueue, Exchange.Name, replyQueue);

            var sendProps     = Channel.CreateBasicProperties();
            var correlationId = Guid.NewGuid().ToString();

            sendProps.CorrelationId = correlationId;
            sendProps.ReplyTo       = replyQueue;

            // Post our message.
            Channel.BasicPublish(Exchange.Name, routingKey, sendProps, MessageHandler.Encode(value));

            // Wait for a response.
            var replyCollection = new AsyncQueue <MessageResponse <TResponse> >();

            void Consume(object sender, BasicDeliverEventArgs ea)
            {
                if (ea.BasicProperties.CorrelationId == correlationId)
                {
                    var reply = new MessageResponse <TResponse>();
                    if (ea.BasicProperties.Type == nameof(Exception))
                    {
                        reply.Success = false;
                        reply.Error   = MessageHandler.Decode <ErrorMessage>(ea.Body);
                    }
                    else
                    {
                        reply.Success  = true;
                        reply.Response = MessageHandler.Decode <TResponse>(ea.Body);
                    }
                    replyCollection.Enqueue(reply);
                }
            }

            ConsumeQueue(replyQueue, Consume);

            // Wait for something to be added to the collection, then return it.
            return(await replyCollection.DequeueAsync(millisecondsTimeout, cancellationToken));
        }