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
}