RabbitMQ 官方NET教程(一)【介绍】
本教程假定RabbitMQ已在标准端口(5672)上的localhost上安装并运行。如果使用不同的主机,端口或凭据,连接设置将需要调整。
RabbitMQ是一个消息代理:它接受并转发消息。 您可以将其视为邮局:当您将要发布的邮件放在邮箱中时,您可以确信Postman先生最终会将邮件发送给收件人。 在这个比喻中,RabbitMQ是一个邮箱,邮局和邮递员。
RabbitMQ和邮局之间的主要区别在于它不处理纸张,而是接受,存储和转发二进制数据块的消息。
RabbitMQ和消息传递一般使用一些术语。
生产意味着什么不仅仅是发送。发送消息的程序是一个`producer`:
队列是居住在RabbitMQ中的邮箱的名称。 虽然消息流过RabbitMQ和您的应用程序,但它们只能存储在队列中。 队列只受主机的内存和硬盘限制的限制,它本质上是一个大的消息缓冲区。 许多生产者可以发送到一个队列的消息,许多消费者可以尝试从一个队列接收数据。 这是我们如何代表一个队列:
消费具有与接收相似的含义。 消费者是一个主要等待接收消息的程序。
请注意,生产者,消费者和broker不必驻留在同一个主机上; 确实在大多数应用程序中,它们不是。
"Hello World"
(使用.NET / C#客户端)
在本教程的这一部分,我们将在C#
中编写两个程序; 发送单个消息的生产者,以及消费者接收消息并将其打印出来。 我们将介绍.NET API中的一些细节,专注于这个非常简单的事情,只是为了开始。 这是一个Hello World
的消息传递。
在下图中,P
是我们的生产者,C
是我们的消费者。 中间的框是队列 - RabbitMQ代表消费者的消息缓冲区。
.NET客户端库
RabbitMQ讲多种协议。 本教程使用AMQP 0-9-1,它是一种开放的通用协议,用于消息传递。 有许多不同语言的RabbitMQ客户端。 我们将使用RabbitMQ提供的.NET客户端。
客户端支持.NET Core以及.NET Framework 4.5.1+。 本教程将使用.NET Core,因此您将确保安装并在PATH中。
您也可以使用.NET Framework完成本教程,但是安装步骤将不同。
客户端通过nuget分发,但也可以作为归档下载。
本教程假定您在Windows上使用powershell。 在OSX / Linux上几乎任何shell都可以工作。
建立
首先让我们验证你在PATH中有.NET Core工具链:
dotnet --help
现在让我们生成两个项目,一个是生产者,一个是消费者:
dotnet new console --name Send
mv Send/Program.cs Send/Send.cs
dotnet new console --name Receive
mv Receive/Program.cs Receive/Receive.cs
这将创建两个名为Send
和Receive
的新目录。
然后我们添加客户机依赖关系。
cd Send
dotnet add package RabbitMQ.Client
dotnet restore
cd ../Receive
dotnet add package RabbitMQ.Client
dotnet restore
现在我们设置了.NET项目,我们可以编写一些代码。
发送
我们将致电我们的消息发布者(sender) Send.cs
和我们的消息消费者 (receiver) Receive.cs。 发布者将连接到RabbitMQ,发送单个消息,然后退出。
在Send.cs
中,我们需要使用一些命名空间:
using System;
using RabbitMQ.Client;
using System.Text;
设置类:
class Send
{
public static void Main()
{
...
}
}
那么我们可以创建一个到服务器的连接:
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,并且没有看到“已发送”消息,那么您可能会挠头,想知道什么地方可能是错误的。
也许broker开始没有足够的可用磁盘空间(默认情况下,它至少需要50 MB空闲),因此拒绝接受消息。
检查broker日志文件以确认并减少限制(如有必要)。 配置文件文档将显示如何设置disk_free_limit
。
接收
这就是我们的发布者。 我们的消费者是从RabbitMQ被推送消息,所以不同于发布单个消息的发布者,我们将继续运行,以收听消息并打印出来。
代码(在Receive.cs
中)具有与Send
几乎相同的using 语句:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
设置与发布者相同; 我们打开一个连接和一个通道,并声明我们要消费的队列。注意这匹配Send
发布者的队列。
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);
...
}
}
}
}
请注意,我们也在这里声明队列。 因为我们可能会在发布者之前启动消费者,所以我们要确保队列存在,然后再尝试从中消费消息。
我们即将告诉服务器将队列中的消息传递给我们。 由于它将异步地推送我们的邮件,所以我们提供一个回调。 那就是EventingBasicConsumer.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();
}
}
}
所有整合起来
打开两个终端
运行消费者:
cd Receive
dotnet run
然后运行生产者:
cd Send
dotnet run
消费者将通过RabbitMQ打印从发布者获得的消息。 消费者将继续运行,等待消息(使用Ctrl-C
停止它),所以尝试从另一个终端运行发布者。
RabbitMQ 官方NET教程(一)【介绍】的更多相关文章
- RabbitMQ 官方NET教程(三)【发布/订阅】
上一篇博客中,我们实现了工作队列,并且我们的工作队列中的一个任务只会发给一个工作者,除非某个工作者未完成任务意外被杀死,会转发给另外的工作者.在这部分中,我们会做一些完全不同的事情 - 我们会向多个消 ...
- RabbitMQ 官方NET教程(六)【RPC】
在第二个教程中,我们学习了如何使用Work Queues在多个工作者之间分配耗时的任务. 但是如果我们需要在远程计算机上运行功能并等待结果怎么办? 那是一个不同的模式. 此模式通常称为远程过程调用或R ...
- RabbitMQ 官方NET教程(五)【Topic】
在上一个教程中,我们改进了我们的日志记录系统.我们使用direct类型转发器,使得接收者有能力进行选择性的接收日志,,而非fanout那样,只能够无脑的转发 虽然使用direct类型改进了我们的系统, ...
- RabbitMQ 官方NET教程(四)【路由选择】
在上一个教程中,我们构建了一个简单的日志记录系统. 我们能够广播日志消息给所有你的接收者. 在本教程中,我们将为其添加一个功能 - 我们将让日志接收者可以仅订阅一部分消息. 例如,我们将能够仅将关键的 ...
- RabbitMQ 官方NET教程(二)【工作队列】
这篇中我们将会创建一个工作队列用来在工作者(consumer)间分发耗时任务. 工作队列的主要任务是:避免立刻执行资源密集型任务和避免必须等待其完成.相反地,我们进行任务调度:我们把任务封装为消息发送 ...
- RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现)
RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现) 在上一个教程中,我们创建了一个工作队列. 工作队列背后的假设是,每个任务都恰好交付给一个worker处理. 在这 ...
- RabbitMQ官方教程二 Work Queues(GOLANG语言实现)
RabbitMQ官方教程二 Work Queues(GOLANG语言实现) 在第一个教程中,我们编写了程序来发送和接收来自命名队列的消息. 在这一部分中,我们将创建一个工作队列,该队列将用于在多个wo ...
- RabbitMQ Go客户端教程3——发布/订阅
本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第三篇--发布/订阅. 这些教程涵盖了使用RabbitMQ创建消息传递 ...
- Tensorflow 官方版教程中文版
2015年11月9日,Google发布人工智能系统TensorFlow并宣布开源,同日,极客学院组织在线TensorFlow中文文档翻译.一个月后,30章文档全部翻译校对完成,上线并提供电子书下载,该 ...
随机推荐
- 怎么选择最适合自己的Linux培训机构?
Linux培训已经成为入门Linux的一个重要途径,它的优势在于学习知识的系统性.快速性和实用性.Linux培训毕业的学员大多数拥有较强的实战动手能力,能够较快上手,更符合企业需求. 不过,大部分同学 ...
- Luogu P1629 邮递员送信
P1629 邮递员送信 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要 ...
- 46.颜色+品牌下钻分析时按最深层metric进行排序
主要知识点: 在做下钻分析时的排序 需求,以颜色进行bucket,这里bucket里面的doc以其各品牌的平均价格排序, GET /tvs/sales/_search { " ...
- 8.mysql执行语句的顺序
mysql执行语句的顺序 一.group by + where group by 字句和where条件语句结合在一起使用,where在前,group by 在后.即先对select xx fr ...
- hdu2013 蟠桃记【C++】
蟠桃记 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu2002 计算球体积【C++】
计算球体积 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- 【1657: [蓝桥杯][算法训练VIP]】统计单词个数
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 设dp[i][j]表示前i个字符分成j个部分的最多匹配单词个数. 则dp[i][j] = dp[prei][j-1] + get_num(pr ...
- noip模拟赛 同余方程组
分析:这道题一个一个枚举都能有70分...... 前60分可以用中国剩余定理搞一搞.然而并没有枚举分数高......考虑怎么省去不必要的枚举,每次跳都只跳a的倍数,这样对前面的式子没有影响,为了使得这 ...
- Sencha Toucha 2.1 文件上传
javascript代码: Ext.onReady(function() { Ext.create('Ext.form.Panel', { title: 'Upload a Photo', width ...
- MySQL Master High Available 理论篇(一)