本文已参与「新人创作礼」活动,一起开启掘金创作之路。
接上篇(Windows RabbitMQ 安装&配置 - 掘金 (juejin.cn))
五、编写测试脚本
- 创建两个C#控制台项目(本文使用vs2019),分别作为消息发布者和消息订阅者。.Net Framework框架版本选择为4.6.1
- 两个工程创建后,都需要添加RabbitMQ包。(安装过程有弹窗,确定即可)
- 消息发布者代码(publisher.cs):每隔150ms,向队列TestQueue1发送一条消息
using System;
using System.Text;
using System.Threading;
using RabbitMQ.Client;
namespace publisher
{
class Program
{
static void Main(string[] args)
{
//基本登录信息
var factory = new ConnectionFactory()
{
HostName = "192.168.123.29",
VirtualHost = "visual_knitting_machine",
UserName = "admin",
Password = "123456",
Port = 5672
};
//创建连接
using (var connection = factory.CreateConnection())
{
//分配channel
using (var channel = connection.CreateModel())
{
for (int i = 1; i < 1000; i++)
{
//描述队列
channel.QueueDeclare(
queue: "TestQueue1",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null
);
//要发送的消息
string message = "Hello World! -- " + i.ToString();
var body = Encoding.UTF8.GetBytes(message);
//发布消息
channel.BasicPublish(
exchange: "myTestExchange",
routingKey: "queue1_routingKey",
basicProperties: null,
body: body
);
Console.WriteLine(" {0} Sent \'{1}\'", i.ToString(), message);
Thread.Sleep(150);
}
}
}
}
}
}
4. 消息订阅者代码(consumer.cs):每隔200ms,从队列消费一条消息。消费者可以有多个。
using System;
using System.Text;
using System.Threading;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
namespace consumer
{
class Program
{
static EventingBasicConsumer consumer;
static IConnection connection;
static IModel channel;
static void Main(string[] args)
{
// 禁用控制台快速编辑模式,防止窗口假死。
// 假死后会阻塞程序,导致无法接受消息
// 可通过按回车解除假死状态
ConsoleUtil.DisbleQuickEditMode();
try
{
var factory = new ConnectionFactory()
{
HostName = "192.168.123.29",
VirtualHost = "visual_knitting_machine",
UserName = "admin",
Password = "123456",
Port = 5672
};
connection = factory.CreateConnection();
channel = connection.CreateModel();
//队列声明
channel.QueueDeclare("TestQueue1", true, false, false, null);
//公平分发,一次只为某个消费者发送一条消息,
//否则会出现其他消费者拿不到消息的情况
//也可设置一次接受多条消息,将1设置n即可。
channel.BasicQos(0, 1, false);
//构建消费者实例
consumer = new EventingBasicConsumer(channel);
//消息接收后的事件委托,异步,非阻塞。
consumer.Received += OnReceiveMessage;
//启动消费者
//关闭自动确认,避免一次性将消息全部消费
channel.BasicConsume("TestQueue1", false, consumer);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//此循环无特殊意义,用来防止控制台自动关闭。
while (true) { }
}
static void OnReceiveMessage(object sender, BasicDeliverEventArgs e)
{
//手动确认消息被消费,只有确认消费后,RabbitMQ才会重新为该消费者发送新消息
channel.BasicAck(e.DeliveryTag, false);
var body = e.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
if (!string.IsNullOrEmpty(message))
{
Console.WriteLine(" Received '{0}'", message);
}
Thread.Sleep(200);
}
}
}