0

I am new to rabbit mq. I have implemented publisher and subscriber method to push and read the message.

I am not able to read the messages which are already pushed into the queue. For example, my subscriber project is down and the publisher application is running. Publisher pushes the data to rabbit mq. Now I starting the subscriber application. My method is subscribed and successfully but I am not getting the messages which are already pushed.

MessageQueueBase.cs

                ConnectionFactory connectionFactory = new ConnectionFactory();

                //Start :Connectoin Factory for RabbitMQ
                connectionFactory.HostName = QueueSetting.MessageQueueHostName;
                connectionFactory.UserName = QueueSetting.MessageQueueUserName;
                connectionFactory.Password = QueueSetting.MessageQueuePassword;
                connectionFactory.VirtualHost = "/";
                if(QueueSetting.Port > 0 )
                {
                    connectionFactory.Port = QueueSetting.Port;
                }

                //End :Connectoin Factory for RabbitMQ

                Connection = connectionFactory.CreateConnection();
                Model = Connection.CreateModel();

                bool durable = true;

                if (!String.IsNullOrEmpty(QueueSetting.MessageQueueExchangeName))
                {
                    Model.ExchangeDeclare(QueueSetting.MessageQueueExchangeName, QueueSetting.ExchangeType, durable, false);
                }

Publisher.cs

public class QueuePublisher : MessageQueueBase, IQueuePublisher
    {
        IBasicProperties basicProperties;
        private bool queueReachable = false;

        public QueuePublisher(QueueSettings queueSetting)
            : base(queueSetting)
        {
            queueReachable = base.ConnectToRabbitMQ();
            basicProperties = Model.CreateBasicProperties();
            basicProperties.Persistent = true;
        }


        public void SendMessage<T>(T data)
        {
            if (!queueReachable)
            {
                throw new Exception(string.Format($"Unable to reach the queue { QueueSetting.MessageQueueExchangeName }"));   // TODO: Pass proper exception here.
            }

            var message = MessageQueueHelpers.Serialize(data);
            Model.BasicPublish(QueueSetting.MessageQueueExchangeName, string.Empty, basicProperties, message);
        }


        public void SendMessage<T>(T data, QueueRoutingKey routingKey)
        {
            if (!queueReachable)
            {
                throw new Exception(string.Format($"Unable to reach the queue {QueueSetting.MessageQueueExchangeName}"));   // TODO: Pass proper exception here.
            }

            var message = MessageQueueHelpers.Serialize(data);
            Model.BasicPublish(QueueSetting.MessageQueueExchangeName, routingKey.ToString(), basicProperties, message);

        }

Subscriber.cs

public class QueueSubscriber : MessageQueueBase, IQueueSubscriber
    {
        private Subscription mSubscription;
        private QueueRoutingKey routingKey;
        private bool queueReachable = false;
        private string queueName = string.Empty;


        public QueueSubscriber(QueueSettings queueSetting)
            : base(queueSetting)
        {
            routingKey = queueSetting.RouteKey;
            queueReachable = base.ConnectToRabbitMQ();
        }


        private delegate void ConsumeDelegate();
        Action<byte[]> messageReceived;


        public void StartSubscribe(Action<byte[]> onMessageReceived)
        {
            if (onMessageReceived == null)
            {
                throw new ArgumentNullException("onMessageReceived", "Subscriber method is not found");
            }

            if (!queueReachable)
            {
                throw new Exception(string.Format($"Unable to reach the queue {QueueSetting.MessageQueueExchangeName}"));   // TODO: Pass proper exception here.
            }

            messageReceived = onMessageReceived;
            Model.BasicQos(0, 1, false);
            queueName = Model.QueueDeclare();
            Model.QueueBind(queueName, QueueSetting.ExchangeType, routingKey.ToString());
            IsConsuming = true;
            ConsumeDelegate c = new ConsumeDelegate(Consume);
            c.BeginInvoke(null, null);
        }


        /// <summary>Trigger Consume method</summary>
        private void Consume()
        {
            bool autoAck = false;

            //Create a subscription
            mSubscription = new Subscription(Model, queueName, autoAck);

            while (IsConsuming)
            {
                BasicDeliverEventArgs e = mSubscription.Next();
                byte[] body = e.Body;
                messageReceived(body);
                mSubscription.Ack(e);
            }
        }

Pushing my messages as

publisher.SendMessage(acknowledgement, routingKey);

Subscribing method as

IQueueSubscriber subscriber = new QueueSubscriber(queueSettings);
            subscriber.StartSubscribe(ProcessData);

void ProcessData(byte[] data)
{
   // Deserialize the data and do work
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Karthikeyan
  • 299
  • 1
  • 10
  • 25
  • Can you check the queue names which you are using in Publisher and Consumer both are of same - case and check in rabbit mq portal if the messages are getting added to proper queue. – Baskar Rao Dec 11 '17 at 21:19
  • Yes. Using the same queue name for both. Subscriber triggered when started before starting of publisher. – Karthikeyan Dec 12 '17 at 13:41

0 Answers0