【译】RabbitMQ:"Hello World"
简介
RabbitMQ是一个消息代理。从本质上讲,它从消息生产者处接收消息,然后传递给消息的消费者。它在消息的生产者和消费者之间根据你指定的规则对消息进行路由、缓存和持久化。
RabbitMQ通常使用如下术语:
- 生产(Producing),表示消息的发送。发送消息的程序被称为生产者。我们画一个图来表示它,如下所示:

- 队列(Queue),表示邮箱的名称,它存在于RabbitMQ服务器中。尽管消息在RabbitMQ和你的应用程序间流转,但它们只能存储与RabbitMQ内部的队列中。队列不会有任何限制,它可以存放任意多的消息,就像一个无限量的缓存一般。多个生产者可以向同一个队列发送消息,多个消费者也可以尝试从同一个队列中读取消息。一个队列可以被画成下面这样在其上有一个名称的图形:

- 消费(Consuming),表示消息的接收。消费者表示通常都在等待接收消息的程序。画图的时候给它标记一个“C”:

需要注意的是,生产者、消费者和代理并不必驻留于同一个服务器上面;通常情况下,他们是分部在不同的机器上面的。
“Hello World“
使用.NET/C#客户端
在教程的这一部分,我们将用C#写两个程序;一个发送一条信息的生产者和一个接收并打印消息的消费者。我们会略过.NET API的一些细节,仅仅专注于如何完成这个简单的程序,传输内容为“Hello World”的消息。
下图中,“P”表示生产者,“C”表示消费者。中间的方框,表示一个队列--RabbitMQ为消费者提供的一个消息缓存。

.NET 客户端库
RabbitMQ遵循AMQP协议,一个关于消息发送的开放、通用协议。现在已经有很多不同编程语言实现的AMQP的客户端。我们将使用由RabbitMQ提供的.NET客户端。
下载客户端库的包,按照描述去检查它的签名。提取包的内容,把“RabbitMQ.Client.dll”程序集复制到你的工作目录下。
你需要确认你的系统中能找到C#的编译器csc.exe,你可能需要把目录“;C:\WINDOWS\Microsoft.NET\Framework\v3.5”(需要根据你实际的安装情况,修改目录中.NET版本)添加到你的Path中。
现在我们已经有了.NET客户端的二进制程序,可以写些代码了。
发送(Sending)

我们把消息的发送者称为Send.cs,消息的接收者称为Receive.cs。消息发送者将连接到RabbitMQ,发送一条消息,然后退出。
在Send.cs中,我们需要用到一些命名空间:
using System;
using RabbitMQ.Client;
using System.Text;
设置类
class Send
{
public static void Main()
{
...
}
}
然后创建一个到RabbitMQ服务的链接
class Send
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
...
}
}
}
}
该链接抽象了套接字连接,为我们关注协议版本协定和身份认证等。在这里,我们连接到了一个本地的代理,因此使用的是localhost。如果我们想连接到其他机器的代理,只需要简单在在这里指定该机器的名称或者Ip地址即可。
接下来我们创建信道(Channel),完成工作的很多API都在里面。
为了发送消息,我们必须申明一个队列,然后才能将消息发布其中:
using System;
using RabbitMQ.Client;
using System.Text; class Send
{
public static void Main()
{
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!";
var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "",
routingKey: "hello",
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent {0}", message);
} Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
申明一个队列是幂等的,它仅仅会在申明的队列不存在于RabbitMQ中时才被创建。消息的内容是字节数组,所以,你可以使用任何喜欢的方式对消息进行编码。
当上面的代码运行结束,信道和链接将会被释放。
发送无法执行
如果这是你第一次使用RabbitMQ,而且未看到已发送的消息,你一定会搔首疑惑是出了什么问题。也许是因为代理运行在没有足够空闲硬盘空间的机器上(默认情况下,代理需要至少50MB的空闲空间)而导致拒绝接收消息。通过查看代理的日志文件可以确认,同时如果有必要降低该项限制。配置文件文档可以告诉你如何设置(disk_free_limit)。
接收
上面那些是关于发送者的。RabbitMQ将消息压入接收者,所以和发布一条消息的发送者不一样,我们要保持接收者一直运行着去监听消息然后打印出来。

Receive.cs的代码需要引用和Send.cs中差不多相同的命名空间:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
类的设置和发送者是相同的;我们打开一个链接和一个信道,申明一个我们将要消费的队列。注意队列需要和发送者中申明的队列相匹配。
class Receive
{
public static void Main()
{
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);
...
}
}
}
}
注意在这里申明的这个队列。我们可能在运行发送者前运行接收者,需要确保在消费这个队列之前队列已经存在。
我们将要告诉RabbitMQ服务从哪个队列传递消息给我们。因为该队列将压入异步消息给我们,我们提供回调。这就是EveningBasicConsumer.Received事件处理器做的事情了。
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text; class Receive
{
public static void Main()
{
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的.NET客户端程序集,然后编译Send.cs和Receive.cs。我们将使用命令行(cmd.exe和csc)编译和运行这些代码。或者你可以使用Visual Studio。
$ csc /r:"RabbitMQ.Client.dll" Send.cs
$ csc /r:"RabbitMQ.Client.dll" Receive.cs
然后运行可执行文件
$ Send.exe
接着运行接收者
$ Receive.exe
接收者会打印从RabbitMQ接收到的消息。接收者一直运行等待新消息(使用Ctrl+C中止),所以可以尝试在不同的终端运行发送者。
如果你希望在队列上做检查,使用rabbitmqctl list_queues.
Hello World!
现在是时候进入到第二部分去创建一个工作队列了。
原文链接:http://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html
【译】RabbitMQ:"Hello World"的更多相关文章
- [译]RabbitMQ教程C#版 - “Hello World”
[译]RabbitMQ教程C#版 - “Hello World” 先决条件本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需 ...
- [译]rabbitmq 2.5 Where’s my message? Durability and you
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. There’s a dirty secret about creating queues and exchanges in ...
- [译]rabbitmq 2.4 Multiple tenants: virtual hosts and separation
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. With exchanges, bindings, and queues under your belt, you mig ...
- [译]rabbitmq 2.2 Building from the bottom: queues
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. You have consumers and producers under your belt, and now you ...
- [译]rabbitmq 2.1 Consumers and producers (not an economics lesson)
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. For now, all you need to know is that producers create messag ...
- [译]RabbitMQ教程C#版 - 工作队列
先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...
- [译]RabbitMQ教程C#版 - 远程过程调用(RPC)
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 主题
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 路由
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- [译]RabbitMQ教程C#版 - 发布订阅
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
随机推荐
- java-String基础篇
一.String字符串理解 java字符串类,包含了字符串的值和实现字符串相关操作的一些方法 1.String字符串可分静态字符串和动态字符串 静态初始化字符串:String s1 = "h ...
- Hadoop的I/O操作
HDFS的数据完整性 检验数据是否损坏最常见的措施是:在数据第一次引入系统时计算校验和并在数据通过一个不可靠通道进行传输时再次计算校验和,这样就能发现数据是否被损坏.HDFS会对写入的所有数据计算校验 ...
- javascript中的对象之间继承关系
相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象 ...
- 微信公众号开发中遇到的几个bug
一.测试自定义菜单接口时中文菜单名显示为null 设置的中文菜单名,中文未经过编码和解码过程,设置的中文菜单名在最后的微信服务器返回的json格式数据中显示为null. 解决办法:将中文先用uneco ...
- MFC中的各种DC区别
转载自:xntop的<区别MFC中的CClientDC.CWindowDC.CPaintDC.CMetaFileDC> CClientDC及其子类 1. CClientDC类只能在客户区绘 ...
- MFC webbrowser读取文档的meta分析
IDispatch* pDisp = NULL; IDispatch* pDisp2 = NULL; IHTMLDocument2 *pHtmlDoc2 = NULL; IHTMLElementCol ...
- Appium for Mac 环境准备篇
之前写过一篇Appium for windows的文章,因为是09年的T400,启动Android模拟器的时候死机三次,那就公司申请台Macbook air吧,15寸的Macbook Pro实在太重了 ...
- Sass浅谈
对于一名前端开发来说,CSS并不陌生,几乎每天都在和CSS打交道.相处久了就会觉得CSS有些许的机械化,有些许的无趣:就会觉得写CSS很多时候都是在做一些复制粘贴性的工作,布局排版,颜色设置,边框属性 ...
- js实现一套代码来控制所有的运动,图片的淡入淡出,winth,height的变宽
介绍了那么多运动,這次一套代码实现所有运动 1.html代码和css代码,只是定义一个div <style> div{ width:200px; height:200px; margin: ...
- 新建jsp报错“The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path”
今天新建jsp文件时,就报错“Visual Page Editor has experimental support for Windows 64-bit”,然后刚好stackoverflow上面有这 ...