Exemplo n.º 1
0
        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;

        }
Exemplo n.º 2
0
        //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;
        }