C# 消息队列
阅读目录
1. 消息队列是什么?
2. 常见的消息队列框架有哪些?
3. MSMQ介绍
4. RabbitMQ介绍
消息队列是什么
简单的理解就是将消息添加一个队列中,使用时在从这个队列中取出来。那么消息什么?队列又是什么呢?
消息:说白了就是交互的内容,可以是文字、图片、视频等等。
队列:一种先进先出的存储格式。
消息队列提供保证消息传递,高效的路由、安全和基于优先级的消息。它可以用来实现需要高性能的异步和同步场景的解决方案。
常见的消息队列框架有哪些?
业内有很多种消息队列框架和中间件,目前使用过的只有RabbitMQ和微软的MSMQ,接下来重点介绍这两种。
MSMQ介绍
Window系统下自带了微软自家的消息队列框架——MSMQ,是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。
一、安装MSMQ
首先,看看是否已经启用MSMQ服务,打开服务窗体,如果能如找到MSMQ服务,说明已经启用,如下图:
如果没有看到该服务,点击 控制面板-打开或关闭Windows功能,选中MSMQ项,再点击“确定”按钮即可启用MSMQ服务,如下图:
二、支持类型
MSMQ 支持两种类型的消息: XML 和二进制。
三、示例代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Messaging; namespace QiDaShengDemo { class Program { static void Main(string[] args) { MessageQueue messageQueue = null; //判断指定的路径是否存在“消息队列”队列,如果存在直接初始化,并设置好说明 //否则在指定的路径中创建“消息队列” if (MessageQueue.Exists(@".\Private$\MyQueues")) { messageQueue = new MessageQueue(@".\Private$\MyQueues"); messageQueue.Label = "Testing Queue"; } else { messageQueue = MessageQueue.Create(@".\Private$\MyQueues"); messageQueue.Label = "New Create Queue"; } //发送对象到消息队列中,并设置好标签 messageQueue.Send("First ever Message is sent to MSMQ", "Title"); //设置消息类型 messageQueue.Formatter = new XmlMessageFormatter(new string[] { "System.String" }); foreach (Message msg in messageQueue) { string readMessage = msg.Body.ToString(); Console.WriteLine(readMessage); } messageQueue.Purge(); Console.Read(); } } }
RabbitMQ介绍
RabbitMQ是一个非常流行的消息队列框架,使用简单,能够使用于当前所有主要的操作系统,并且是开源的,目前最新的版本为3.6.5。
RabbitMQ安装
卸载历史版本
如果本地之前已经安装过Erlang(一种编程语言)虚拟机,,要先卸载。
安装RabbitMQ Server
首先,要先下载 Erlang Windows Binary File,下载之后安装即可。
然后,在下载rabbitmq-server-3.6.5.exe,下载之后点击安装即可,这样RabbitMQ Server就安装成功了,安装成功之后在“开始”菜单可以看到如下信息:
如上图所示,我们可以重新安装、移除、开始、停止 RabbitMQ 服务。
RabbitMQ示例
简单的进程通讯,一个Producer发送一条message到消息队列中,一个Consumer从消息队列中接收到这条message。
新建一个控制台程序,发送端示例代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using RabbitMQ.Client; namespace RabbitMQ.Send { class Program { static void Main(string[] args) { var factory = new ConnectionFactory() { HostName="localhost"}; using (var connection = factory.CreateConnection()) using (var channel=connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive:false, autoDelete:false, arguments:null ); string message = "Hello world qds!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange:"", routingKey:"hello", basicProperties:null, body:body ); Console.WriteLine(" [x]send {0}",message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }
新建一个控制台程序,接收端示例代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using RabbitMQ.Client; using RabbitMQ.Client.Events; namespace RabbitMQ.Receive { class Program { static void Main(string[] args) { var factory = new ConnectionFactory() { HostName="localhost"}; using (var connection = factory.CreateConnection()) using (var channel=connection.CreateModel()) { channel.QueueDeclare(queue:"hello", durable:false, exclusive:false, autoDelete:false, arguments:null ); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model,ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "hello", noAck: true, consumer:consumer ); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } } }
两个工程编程成功之后,先执行RabbitMQ.Send.exe,再执行RabbitMQ.Receive.exe,
结果如下:
想了解更多,可参考RabbiMQ官网:http://www.rabbitmq.com/
参考:
[1].http://www.cnblogs.com/tenghoo/archive/2009/11/05/1596456.html
[2].http://www.cnblogs.com/danielWise/archive/2011/02/28/1966808.html
[3].http://www.cnblogs.com/gossip/p/4373547.html
[4].http://www.cnblogs.com/shanyou/archive/2012/10/27/2742979.html