private bool TryGetRequest(ConcurrentQueueingConsumer consumer, out HttpRequestPacket request, out MessageDispatch dispatch) { request = null; dispatch = null; BasicDeliverEventArgs item; if (!consumer.TryInstantDequeue(out item, throwIfClosed: false)) { return false; } //TODO: Pool MessageDispatch //Get message dispatch = new MessageDispatch { Consumer = consumer, Delivery = item }; //Deserialize message bool wasDeserialized = true; try { request = HttpRequestPacket.Deserialize(item.Body); } catch { wasDeserialized = false; } if (wasDeserialized) { //Add/Update Subscriber-Id header request.Headers[Common.Shared.SUBSCRIBER_ID_HEADER] = this.subscriberIdHeader; //Add redelivered header if item was redelivered. if (item.Redelivered) { request.Headers[Common.Shared.REDELIVERED_HEADER] = TRUE_STRING_ARRAY; } } //Reject message if deserialization failed. else if (!wasDeserialized && Settings.AckBehavior != SubscriberAckBehavior.Automatic ) { consumer.Model.BasicReject(item.DeliveryTag, false); return false; } return true; }
//TODO: REMOVE LATER: This method is never called because the DirectReplyToStrategy is used when the client decides to use //the direct reply to feature. /// <summary> /// Discovers the Direct reply-to queue name ( https://www.rabbitmq.com/direct-reply-to.html ) by messaging itself. /// </summary> private static string DiscoverDirectReplyToQueueName(IModel channel, string indirectReplyToQueueName) { DeclareIndirectReplyToQueue(channel, indirectReplyToQueueName); var receiver = new ConcurrentQueueingConsumer(channel); var receiverTag = channel.BasicConsume(indirectReplyToQueueName, true, receiver); channel.BasicPublish(String.Empty, indirectReplyToQueueName, true, new BasicProperties { ReplyTo = RPCStrategyHelpers.DIRECT_REPLY_TO_QUEUENAME_ARG }, new byte[0]); BasicDeliverEventArgs delivery; using (ManualResetEventSlim messageReturned = new ManualResetEventSlim()) { EventHandler<BasicReturnEventArgs> returnHandler = null; Interlocked.Exchange(ref returnHandler, (a, e) => { messageReturned.Set(); try { receiver.Model.BasicReturn -= returnHandler; } catch { } }); receiver.Model.BasicReturn += returnHandler; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); while (!receiver.TryInstantDequeue(out delivery, throwIfClosed: false)) { Thread.Sleep(1); if (watch.Elapsed > TimeSpan.FromSeconds(10) || messageReturned.IsSet) { break; } } watch.Stop(); if (!messageReturned.IsSet) { try { receiver.Model.BasicReturn -= returnHandler; } catch { } } try { channel.BasicCancel(receiverTag); } catch { } } if (delivery == null) { throw new InvalidOperationException("Unable to determine direct reply-to queue name."); } var result = delivery.BasicProperties.ReplyTo; if (result == null || result == RPCStrategyHelpers.DIRECT_REPLY_TO_QUEUENAME_ARG || !result.StartsWith(RPCStrategyHelpers.DIRECT_REPLY_TO_QUEUENAME_ARG)) { throw new InvalidOperationException("Discovered direct reply-to queue name (" + (result ?? "null") + ") was not in expected format."); } return result; }