RabbitMQ C#验证消息已发送

RabbitMQ C#验证消息已发送,c#,rabbitmq,C#,Rabbitmq,我是RabbitMQ新手,正在尝试写入队列并验证消息是否已发送。如果失败了,我需要知道。 我做了一个假队列来看着它失败,但无论我看到什么都没有执行,当我在寻找ack时,我总是得到一个。我从来没见过基茨纳克 我甚至不确定我是不是Basicaks才是最好的选择 private void button1_Click(object sender, EventArgs e) { var factory = new ConnectionFactory() { HostName

我是RabbitMQ新手,正在尝试写入队列并验证消息是否已发送。如果失败了,我需要知道。 我做了一个假队列来看着它失败,但无论我看到什么都没有执行,当我在寻找ack时,我总是得到一个。我从来没见过基茨纳克

我甚至不确定我是不是Basicaks才是最好的选择

    private void button1_Click(object sender, EventArgs e)
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("task_queue", true, false, false, null);

                var message = ("Helllo world");
                var body = Encoding.UTF8.GetBytes(message);
                channel.ConfirmSelect();

                var properties = channel.CreateBasicProperties();
                properties.SetPersistent(true);
                properties.DeliveryMode = 2;
                channel.BasicAcks += channel_BasicAcks;
                channel.BasicNacks += channel_BasicNacks;
                //fake queue should be task_queue
                channel.BasicPublish("", "task_2queue", true, properties, body);

                channel.WaitForConfirmsOrDie();

                Console.WriteLine(" [x] Sent {0}", message);
            }
        }
    }

    void channel_BasicNacks(IModel model, BasicNackEventArgs args)
    {

    }

    void channel_BasicAcks(IModel model, BasicAckEventArgs args)
    {

    }
你需要一个

正如您所看到的,您可以实现:

交易:

ch.txSelect(); <-- start transaction
ch.basicPublish("", QUEUE_NAME,
                            MessageProperties.PERSISTENT_BASIC,
                            "nop".getBytes());
ch.txCommit();<--commit transaction

我希望这会有所帮助。好的,您总是会收到发送邮件的确认信息,因为“每次邮件都成功传递到默认Exchange。”

PS:您没有直接将消息发送到队列,Exchange收到消息后会给您确认,然后使用路由键(如果有)将消息路由到所有绑定的队列。

对于那些寻找C#答案的人-以下是您需要的

类似这样的内容:(BasicAcks附加了一个事件处理程序-还有BasicAcks)

使用(var connection=FACTORY.CreateConnection())
{
var channel=connection.CreateModel();
channel.ExchangeClare(队列名称,ExchangeType.Fanout,true);
QueueDeclare(队列名称,true,false,false,null);
QueueBind(QUEUE_NAME,QUEUE_NAME,String.Empty,new Dictionary());
channel.BasicAcks+=(发送方,事件参数)=>
{
//执行确认句柄
};
channel.ConfirmSelect();

对于(var i=1;i是轻量级的更快?我确实需要最好的性能。我并不真的需要它保存到IO,而是保存在队列中。如果失败,我需要有回退代码。是的,它更快。事务非常慢,你必须等待同步磁盘操作,并且发布被锁定,直到消息被存储。顺便说一句,轻量级Publisher确认更为复杂,因为如果不想丢失消息,您应该将消息完全映射为链接。我使用了channel.ConfirmSelect();和channel.waitforconfirmsodie();并被告知使用返回事件。我可以通过这种方式看到错误。这会比ch.txSelect()更快吗/txCommit?我将每秒发送大量流量,如10k,并寻求最佳性能的建议。当然,我不会每次都打开连接,但我只做了一天:)WaitForConfirmsOrDie比txCommit快,无论如何,我建议使用WaitForConfirmsOrDie(超时),否则,如果出现问题,您可能会永远阻止发布。如果需要性能,确认发布通常不是好的选择。因此,您可以尝试在多线程中打开更多通道,并使用WaitForConfirmsOrDie(超时)我想你可以有正确的妥协。让我知道你提供的流轻量级例子不是C语言,OP正在使用的OP,你能考虑编辑这个答案并添加一个C实现吗?这是不正确的。在香草AMQP中,如果经纪人接受消息(见方法DOC)它不会回应任何东西。除非你正在使用-这是提问者需要的。
ch.setConfirmListener(new ConfirmListener() {
    public void handleAck(long seqNo, boolean multiple) {
        if (multiple) {
            unconfirmedSet.headSet(seqNo+1).clear();
        } else {
            unconfirmedSet.remove(seqNo);
        }
    }
    public void handleNack(long seqNo, boolean multiple) {
        // handle the lost messages somehow
    }
using (var connection = FACTORY.CreateConnection())
{
    var channel = connection.CreateModel();
    channel.ExchangeDeclare(QUEUE_NAME, ExchangeType.Fanout, true);
    channel.QueueDeclare(QUEUE_NAME, true, false, false, null);
    channel.QueueBind(QUEUE_NAME, QUEUE_NAME, String.Empty, new Dictionary<string, object>());
     channel.BasicAcks += (sender, eventArgs) =>
                {
                    //implement ack handle
                };
    channel.ConfirmSelect();

    for (var i = 1; i <= numberOfMessages; i++)
    {
        var messageProperties = channel.CreateBasicProperties();
        messageProperties.SetPersistent(true);

        var message = String.Format("{0}\thello world", i);
        var payload = Encoding.Unicode.GetBytes(message);
        Console.WriteLine("Sending message: " + message);
        channel.BasicPublish(QUEUE_NAME, QUEUE_NAME, messageProperties, payload);
        channel.WaitForConfirmsOrDie();
    }
}