“持久”和“持久模式”似乎与重新启动有关,而不是与没有订阅者接收消息有关。
我希望RabbitMQ在没有订阅者时将消息保留在队列中。当订户上线时,该订户应该接收该消息。 RabbitMQ可以实现吗?
代码示例:
服务器
namespace RabbitEg
{
class Program
{
private const string EXCHANGE_NAME = "helloworld";
static void Main(string[] args)
{
ConnectionFactory cnFactory = new RabbitMQ.Client.ConnectionFactory() { HostName = "localhost" };
using (IConnection cn = cnFactory.CreateConnection())
{
using (IModel channel = cn.CreateModel())
{
//channel.ExchangeDelete(EXCHANGE_NAME);
channel.ExchangeDeclare(EXCHANGE_NAME, "direct", true);
//channel.BasicReturn += new BasicReturnEventHandler(channel_BasicReturn);
for (int i = 0; i < 100; i++)
{
byte[] payLoad = Encoding.ASCII.GetBytes("hello world _ " + i);
IBasicProperties channelProps = channel.CreateBasicProperties();
channelProps.SetPersistent(true);
channel.BasicPublish(EXCHANGE_NAME, "routekey_helloworld", false, false, channelProps, payLoad);
Console.WriteLine("Sent Message " + i);
System.Threading.Thread.Sleep(25);
}
Console.ReadLine();
}
}
}
}
}
客户端:
namespace RabbitListener
{
class Program
{
private const string EXCHANGE_NAME = "helloworld";
static void Main(string[] args)
{
ConnectionFactory cnFactory = new ConnectionFactory() { HostName = "localhost" };
using (IConnection cn = cnFactory.CreateConnection())
{
using (IModel channel = cn.CreateModel())
{
channel.ExchangeDeclare(EXCHANGE_NAME, "direct", true);
string queueName = channel.QueueDeclare("myQueue", true, false, false, null);
channel.QueueBind(queueName, EXCHANGE_NAME, "routekey_helloworld");
Console.WriteLine("Waiting for messages");
QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(queueName, true, consumer);
while (true)
{
BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
Console.WriteLine(Encoding.ASCII.GetString(e.Body));
}
}
}
}
}
}
答案 0 :(得分:14)
有关durable
和persistent
的含义的解释,请参阅AMQP Reference。
基本上,队列是durable
或non-durable
。前者在经纪人重启后继续存在,后者则没有。
邮件发布为transient
或persistent
。我们的想法是persistent
队列上的durable
消息也应该在代理重启后继续存在。
因此,要获得所需内容,您需要1)将队列声明为durable
,2)将消息发布为persistent
。此外,您可能还想在频道上启用发布商确认;这样,你就会知道经纪人何时承担了这条消息的责任。