RabbitMQ入门教程——.NET客户端使用
众所周知RabbitMQ使用的是AMQP协议。我们知道AMQP是一种网络协议,能够支持符合要求的客户端应用和消息中间件代理之间进行通信。
其中消息代理扮演的角色就是从生产者那儿接受消息,并根据既定的路由规则把接受到的消息发送给消息的处理者又称消费者。由此可以看出RabbitMQ在整个消息发送,处理的过程中有三个比较重要的角色:
生产者:producer,消息生产者,就是投递消息的程序
消息代理:broker,简单来说就是消息队列服务器实体,这里简单理解为我们安装的RabbitMQ服务
消费者:consumer,消息消费者,就是接受消息的程序
接下来我们将以一个简单的控制台程序来实现消息队列的发送及接收(使用.NET版RabbitMQ客户端):
主要功能为: 一个producer发送消息,一个consumer接收消息,并在控制台打印出来。
使用Nuget添加RabbitMQ.Client程序包至项目中
Install-Package RabbitMQ.Client
创建消息的生产者 Producer.cs ,发送一条消息给消费者
- using RabbitMQ.Client;
- using System;
- using System.Text;
- namespace RabbitMQProducer
- {
- public
class Producer - {
- public
static
void Send() - {
- //创建连接连接到RabbitMQ服务器,就是一个位于客户端和Broker之间的TCP连接,建议共用此TCP连接,每次使用时创建一个新的channel即可,
- var factory = new ConnectionFactory();
- IConnection connection = null;
- //方式1:使用AMQP协议URL amqp://username:password@hostname:port/virtual host 可通过http://127.0.0.1:15672/ RabbitMQWeb管理页面查看每个参数的具体内容
- factory.Uri = "amqp://guest:guest@127.0.0.1:5672//";
- connection = factory.CreateConnection();
- ////方式2:使用ConnectionFactory属性赋值
- //factory.UserName = ConnectionFactory.DefaultUser;
- //factory.Password = ConnectionFactory.DefaultPass;
- //factory.VirtualHost = ConnectionFactory.DefaultVHost;
- //factory.HostName = "127.0.0.1"; //设置RabbitMQ服务器所在的IP或主机名
- //factory.Port = AmqpTcpEndpoint.UseDefaultPort;
- //connection = factory.CreateConnection();
- ////方式3:使用CreateConnection方法创建连接,默认使用第一个地址连接服务端,如果第一个不可用会依次使用后面的连接
- //List<AmqpTcpEndpoint> endpoints = new List<AmqpTcpEndpoint>() {
- // new AmqpTcpEndpoint() { HostName="localhost1",Port=5672},
- // new AmqpTcpEndpoint() { HostName="localhost2",Port=5672},
- // new AmqpTcpEndpoint() { HostName="localhost3",Port=5672},
- // new AmqpTcpEndpoint() { HostName="localhost4",Port=5672}
- //};
- //connection = factory.CreateConnection(endpoints);
- using (connection)
- {
- //创建一个消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。类似与Hibernate中的Session
- //AMQP协议规定只有通过channel才能指定AMQP命令,所以仅仅在创建了connection后客户端还是不能发送消息的,必须要创建一个channel才行
- //RabbitMQ建议客户端线程之间不要共用Channel,至少要保证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection
- using (IModel channel = connection.CreateModel())
- {
- //创建一个queue(消息队列)
- channel.QueueDeclare(
- queue: "hello",
- durable: false,
- exclusive: false,
- autoDelete: false,
- arguments: null);
- string message = "你好消费者,我是生产者发送的消息";
- //往队列中发出一条消息 使用了默认交换机并且绑定路由键(route key)与队列名称相同
- channel.BasicPublish(
- exchange: "",
- routingKey: "hello",
- basicProperties: null,
- body: Encoding.UTF8.GetBytes(message));
- Console.WriteLine($"我是生产者,我发送了一条消息{message}");
- Console.WriteLine(" Press [enter] to exit.");
- Console.ReadLine();
- }
- }
- }
- }
- }
注意:1.队列只会在它不存在的时候创建,多次声明并不会重复创建。
2.信息的内容是字节数组,也就意味着可以传递任何数据。
3.创建消息的消费者Consumer.cs ,从队列中获取消息并打印到屏幕
- using RabbitMQ.Client;
- using RabbitMQ.Client.Events;
- using System;
- using System.Text;
- namespace RabbitMQConsumer
- {
- public
class Consumer - {
- public
static
void Receive() - {
- var factory = new ConnectionFactory();
- factory.Uri = "amqp://guest:guest@127.0.0.1:5672//";
- using (var connection = factory.CreateConnection())
- {
- using (var channel = connection.CreateModel())
- {
- //声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列
- channel.QueueDeclare(
- queue: "hello",
- durable: false,
- exclusive: false,
- autoDelete: false,
- arguments: null);
- //创建事件驱动的消费者类型,尽量不要使用while(ture)循环来获取消息
- EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
- consumer.Received += (model, ea) =>
- {
- var body = ea.Body;
- var message = Encoding.UTF8.GetString(body);
- Console.WriteLine(" 我是消费者我接收到消息: {0}", message);
- };
- //指定消费队列
- channel.BasicConsume(queue: "hello",
- noAck: true,
- consumer: consumer);
- Console.WriteLine(" Press [enter] to exit.");
- Console.ReadLine();
- }
- }
- }
- }
- }
消息队列的使用过程大致如下:
- CreateConnection 创建一个连接连接到broker
- CreateModel 创建一个channel 使用它来发送AMQP指令
- ExchangeDeclare 创建一个exchange 对消息进行路由
- QueueDeclare 创建一个queue 消息队列 这是一个装载消息的容器
- QueueBind 把exchange和queue按照路由规则绑定起来
- BasicPublish 往队列中发送一条消息
- BasicConsume 从队列中获取一条消息
exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。
本文中由于使用了默认交换机所以并没有用到 ExchangeDeclare和 QueueBind两个方法
默认交换机实际上是一个由消息代理预先声明好的没有名字(名字为空字符串)的直连交换机。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同
RabbitMQ入门教程——.NET客户端使用的更多相关文章
- RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较
原文:RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 这是网上的一篇教程写的很好,不知原作 ...
- RabbitMQ入门教程(十四):RabbitMQ单机集群搭建
原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...
- RabbitMQ入门教程(十二):消息确认Ack
原文:RabbitMQ入门教程(十二):消息确认Ack 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csd ...
- RabbitMQ入门教程(八):远程过程调用RPC
原文:RabbitMQ入门教程(八):远程过程调用RPC 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.cs ...
- RabbitMQ入门教程(三):Hello World
原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...
- RabbitMQ入门教程(二):简介和基本概念
原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...
- RabbitMQ入门教程(十六):RabbitMQ与Spring集成
原文:RabbitMQ入门教程(十六):RabbitMQ与Spring集成 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https: ...
- RabbitMQ入门教程(十五):普通集群和镜像集群
原文:RabbitMQ入门教程(十五):普通集群和镜像集群 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.c ...
- RabbitMQ入门教程(十三):虚拟主机vhost与权限管理
原文:RabbitMQ入门教程(十三):虚拟主机vhost与权限管理 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...
随机推荐
- Android对话框自定义标题
Android自带的对话框标题不好看,如果我们需要给弹出的对话框设置一个自己定义的标题,可以使用AlertDialog.Builder的setCustomTitle()方法. 定义一个对话框标题的ti ...
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现(转)
使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...
- JavaMail API 详细分解
在使用Spring框架的过程中,它的优势之一就是在于跟其他一些技术的整合,如JavaMail .任务调度.缓存策略等技术.今天就Java Mail详细阐述.JavaMail API是被设计为与协议无关 ...
- JS疑难点和GC原理
js解析与序列化json数据(一)json.stringify()的基本用法: 对象有两个方法:stringify()和parse().在最简单的情况下,这两个方法分别用于把JavaScript对象序 ...
- [moka同学笔记]三、Yii2.0课程笔记(魏曦老师教程)关联字段增加搜索
关联字段增加搜索 post表关联adminuser表,通过post.author_id adminuser.id关联,在YII2.0生成搜索,关联字段搜索时,需要输入关联字段author的id才能搜 ...
- javax.el.PropertyNotFoundException: Property 'name' not found on type java.lang.String
javax.el.PropertyNotFoundException: Property 'name' not found on type java.lang.String javax.el.Bean ...
- NotSerializableException解决方法
NotSerializableException 问题描述: 想要写入对象的时候的时候回抛出NotSerializableException:类名 原因: 写入的对象没有序列化,即没有实现java.i ...
- [deviceone开发]-echart的简单报表示例
一.简介 echart是一个常用的基于h5的报表库.这个例子简单展示了实现折线图,柱状图,圆环图和圆饼图的使用. 并实现和do的非html部分的数据交互. 二.效果图 三.相关下载 https://g ...
- CSS3滚动条-webkit-scrollbar
webkit现在支持拥有overflow属性的区域,列表框,下拉菜单,textarea的滚动条自定义样式. 如果你想跳过介绍,直接看demo的话,请点击demo 滚动条是一个伪元素,可以自定义样式.这 ...
- Javascript数组算法和技巧总结
Js-arrayMethod https://github.com/HerbertKarajan/Js-arrayMethod List unique an array 数组去重 random str ...