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