当前位置:网站首页 / C#开发 / 正文

AY C# RabbitMQ 2019 微笔记4

时间:2018年12月05日 | 作者 : aaronyang | 分类 : C#开发 | 浏览: 391次 | 评论 0

Exchange 发布订阅 1个生产者对多个消费者 

队列是一个存储消息的buffer

image.png

对的,会爬要走路了。

生产者代码如下

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MQ3
{
    class Program
    {
        public static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost", UserName = "ay", Password = "123456", Port = 5672 };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: "logs", type: "fanout");

                var message = GetMessage(args);
                var body = Encoding.UTF8.GetBytes(message);
                channel.BasicPublish(exchange: "logs",
                                     routingKey: "",
                                     basicProperties: null,
                                     body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }

        private static string GetMessage(string[] args)
        {
            return ((args.Length > 0)
                   ? string.Join(" ", args)
                   : "info: Hello.World!");
        }
    }
}

====================www.ayjs.net       杨洋    wpfui.com        ayui      ay  aaronyang=======请不要转载谢谢了。=========

运行,

image.png

image.png

命令行列出rabbitmqctl list_exchanges

image.png

amq.*开头的 默认邮箱,安装好RabbitMQ就有的,暂时用不到。

在以前的代码,我们没有用到exchange,但是仍然可以发消息到队列。那是因为我们发到默认邮箱去了,我们给exchange赋值是空白

 var message = GetMessage(args);    var body = Encoding.UTF8.GetBytes(message);
    channel.BasicPublish(exchange: "",
                         routingKey: "hello",
                         basicProperties: null,
                         body: body);


现在我们代码 声明一个 fanout的 邮箱(交换器),取个名字叫logs

channel.ExchangeDeclare(exchange: "logs", type: "fanout");


临时队列

前面的代码,我们给队列取名字 hello,task_queue还记得吗?命名后,消费者通过名字拿到队列然后 处理消息的。

在这个例子对于我们的logger不重要,我们只关注log内容,

我们可以通过下面,随机取名字。然后一旦消费者断开连接,消息要能删除。

默认,创建的是非 持久化,exclusive,自动删除的队列

ar queueName = channel.QueueDeclare().QueueName;

exclusive queue独占队列,相当于给队列lock了,别人不能拿到。 一般消费者死了,独占队列会被删除。因此用于特定的某些场景。

你占用了,当别人尝试访问,就会报 RESOURCE_LOCKED的错误异常。表示无法获得对 锁定队列的 独占访问权限。


Binding

队列要放入邮箱才好,放进去叫绑定

channel.QueueBind(queue: queueName,
                  exchange: "logs",
                  routingKey: "");

上面代码我没给队列名字,因为我不关心,你也可以写个 产品约定好的名字 ,或者调用临时队列的知识,随机名字。

列出绑定(命令行)

rabbitmqctl list_bindings

image.png


发布消息

   channel.BasicPublish(exchange: "logs",
                                 routingKey: "",
                                 basicProperties: null,
                                 body: body);

上面的exchange的邮箱一定要存在,不然发布失败。

如果队列没有绑定邮箱,消息将会丢失,但这对我们没有问题; 因为如果没有消费者在监听,我们可以安全地丢弃该消息。



消费者:

using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;

class Program
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost", UserName = "ay", Password = "123456", Port = 5672 };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "logs", type: "fanout");

            var queueName = channel.QueueDeclare().QueueName;
            channel.QueueBind(queue: queueName,
                              exchange: "logs",
                              routingKey: "");

            Console.WriteLine(" [*] Waiting for logs.");

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                Console.WriteLine(" [x] {0}", message);
            };
            channel.BasicConsume(queue: queueName,
                                 autoAck: true,
                                 consumer: consumer);

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }

    }
}

消费者先打开,然后打开生产者

image.png


AY 过程理解:

测试1:

把邮箱都删掉,保持干净环境

我们运行消费者:此时通过web管理,看到多了个logs

image.png

对内多了一个amq.genXXXX的名字的queue,

image.png


关闭消费者==》》 临时队列删除了,exchange依旧存在。

image.png


然后运行生产者,不退出,队列没变化

打开消费者,也无法获得消息。

我们生产个消息,消费者不关闭,立即就可以收到消息了。

总结: 消费者连接了在线才可以收到消息。

(由于我们的代码,释放连接,就关闭消费者程序就行了,意味着 消费者死亡,那么临时队列也会被删除了。 满足条件)


接下来运行多个消费者,然后打开生产者,每个消费者都能正确拿到消息了。

image.png

image.png

运行多个,会产生多个临时队列,理解OK。


fanout 就是根据exchange名字来拿消息,没啥过滤在里面,但是你也可以 设计名字,来分配业务。


下面会将 可以过滤的topic,header


关于我以前写的fanout教程: 小坦克


====================www.ayjs.net       杨洋    wpfui.com        ayui      ay  aaronyang=======请不要转载谢谢了。=========













推荐您阅读更多有关于“RabbitMQ,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音号:wpfui,可以看到我的很多作品效果

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

兼容XP到win10,vs2015/2019,最新AYUI:7.6.5.2

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表