rabbitmq官网:
安装rabbitmq:
https://www.rabbitmq.com/install-windows.html
安装指南:
1.首先安装rabbitmq的Erlang依赖,下载地址:
https://www.erlang.org/downloads
下载如图红色箭头指的文件,然后安装Erlang依赖环境
2.然后安装windows版本的rabbitmq-server程序
.NET调用rabbitmq文档:
https://www.rabbitmq.com/dotnet.html
https://www.rabbitmq.com/dotnet-api-guide.html
安装rabbitmq-server后,启动rabbitmq服务器
配置web管理界面,在控制台里面输入命令即可启用:
rabbitmq-plugins enable rabbitmq_management
--web界面,账号密码都为guest:
官网github项目测试参考代码:
https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/master/projects/Unit/TestBasicPublish.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using RabbitMQ.Client.Events;
namespace RabbitMQ.Client.Unit
{
[TestFixture]
public class TestBasicPublish
{
[Test]
public void TestBasicRoundtripArray()
{
var cf = new ConnectionFactory();
using(IConnection c = cf.CreateConnection())
using(IModel m = c.CreateModel())
{
QueueDeclareOk q = m.QueueDeclare();
IBasicProperties bp = m.CreateBasicProperties();
byte[] sendBody = System.Text.Encoding.UTF8.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(m);
var are = new AutoResetEvent(false);
consumer.Received += async (o, a) =>
{
consumeBody = a.Body.ToArray();
are.Set();
await Task.Yield();
};
string tag = m.BasicConsume(q.QueueName, true, consumer);
m.BasicPublish("", q.QueueName, bp, sendBody);
bool waitResFalse = are.WaitOne(2000);
m.BasicCancel(tag);
Assert.IsTrue(waitResFalse);
CollectionAssert.AreEqual(sendBody, consumeBody);
}
}
[Test]
public void TestBasicRoundtripReadOnlyMemory()
{
var cf = new ConnectionFactory();
using(IConnection c = cf.CreateConnection())
using(IModel m = c.CreateModel())
{
QueueDeclareOk q = m.QueueDeclare();
IBasicProperties bp = m.CreateBasicProperties();
byte[] sendBody = System.Text.Encoding.UTF8.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(m);
var are = new AutoResetEvent(false);
consumer.Received += async (o, a) =>
{
consumeBody = a.Body.ToArray();
are.Set();
await Task.Yield();
};
string tag = m.BasicConsume(q.QueueName, true, consumer);
m.BasicPublish("", q.QueueName, bp, new ReadOnlyMemory(sendBody));
bool waitResFalse = are.WaitOne(2000);
m.BasicCancel(tag);
Assert.IsTrue(waitResFalse);
CollectionAssert.AreEqual(sendBody, consumeBody);
}
}
}
}
首先在nuget里面安装rabbitmq客户端,直接在nuget里面搜索RabbitMQ.Client,然后安装
服务端发布消息代码:
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Console_RabbitMqTest_App1
{
class Program
{
static void Main(string[] args)
{
//服务端,生产消息
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "localhost";
factory.UserName = "raadmin";
factory.Password = "raadmin";
//factory.UserName = "guest";
//factory.Password = "guest";
IConnection conn = factory.CreateConnection();
IModel channel = conn.CreateModel();
//channel.ExchangeDeclare(exchangeName, ExchangeType.Direct);
//channel.QueueDeclare(queueName, false, false, false, null);
//channel.QueueBind(queueName, exchangeName, routingKey, null);
channel.QueueDeclare(queue: "testMq",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
//定义已经被处理的消息队列,
channel.QueueDeclare(queue: "testMq_handle",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
for (int i = 0; i < 10000; i++)
{
//发布消息
//IBasicProperties properties = channel.CreateBasicProperties();
//properties.DeliveryMode = 2;//消息持久化
string message = "测试数据"+i+"." +Guid.NewGuid().ToString("N")+"_"+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
var body = Encoding.UTF8.GetBytes(message);
//channel.BasicPublish(exchange: "",
// routingKey: "testMq",
// basicProperties: properties,
// body: body);
channel.BasicPublish(exchange: "",
routingKey: "testMq",
basicProperties: null,
body: body);
Console.WriteLine("发布消息{0}", message);
//System.Threading.Thread.Sleep(3000);
}
channel.Close();
conn.Close();
Console.ReadLine();
}
}
}
另外建立个控制台项目,用于处理消息,
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleHandleMessage
{
class Program
{
static void Main(string[] args)
{
//处理消息
ConnectionFactory factory = new ConnectionFactory();
factory.UserName = "guest";
factory.Password = "guest";
factory.HostName = "localhost";
IConnection conn = factory.CreateConnection();
IModel channel = conn.CreateModel();
//用于写入消息
ConnectionFactory factory5 = new ConnectionFactory();
factory5.HostName = "localhost";
factory5.UserName = "raadmin";
factory5.Password = "raadmin";
factory5.AutomaticRecoveryEnabled = true;//自动连接恢复
IConnection conn5 = factory5.CreateConnection("handle02");
IModel channel5 = conn5.CreateModel();
//*************订阅消息,生产者生产消息后,会主动推送过来
//testMq表示一个队列
channel.QueueDeclare("testMq", false, false, false, null);
var consumer = new EventingBasicConsumer(channel);//消费者
//注册消费者订阅,false获取消息后不会从队列移除,true会移除
channel.BasicConsume("testMq",false, consumer);
//此获取消息事件,处理消息时,会自动从最远的时间开始处理,按顺序来的,最新的消息在最后处理
consumer.Received += (s, e) =>
{
var bodyBytes = e.Body;
var message = Encoding.UTF8.GetString(bodyBytes.ToArray());
//处理消息业务
Task.Run(() =>
{
try
{
LogHelpter.AddLog("收到:" + message);//记录本地txt日志
Console.WriteLine("接收的消息" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + ":" + message + ",ThreadId=" + Thread.CurrentThread.ManagedThreadId);
//确认已经收到消息,此行为通知消息队列移除消息
channel.BasicAck(e.DeliveryTag, false);
}
catch (Exception ex)
{
Console.WriteLine("确认消息报错:" + ex.Message);
LogHelpter.AddLog("确认消息报错:" + ex.Message);//记录本地txt日志
}
});
//记录已经处理的消息,写入另一个队列
try
{
channel5.BasicPublish(exchange: "", routingKey: "testMq_handle", basicProperties: null, body: bodyBytes);
}
catch (Exception ex)
{
LogHelpter.AddLog("记录处理消息异常," + ex.Message);//记录本地txt日志
}
System.Threading.Thread.Sleep(1);//此行代码必须,不然写入队列消息会报错
//报错消息:
//Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=505, text='UNEXPECTED_FRAME - expected content header for class 60, got non content header frame instead', classId=60, methodId=40
};
//channel.Close();
//conn.Close();
Console.ReadLine();
}
}
}
轮询的方式拉取消息
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleHandleMessage
{
class Program
{
static void Main(string[] args)
{
//处理消息
ConnectionFactory factory = new ConnectionFactory();
factory.UserName = "guest";
factory.Password = "guest";
factory.HostName = "localhost";
IConnection conn = factory.CreateConnection();
IModel channel = conn.CreateModel();
//*************轮询拉取消息
BasicGetResult result = channel.BasicGet("testMq",false);
if (result == null)
{
//没有消息
}
else {
IBasicProperties props = result.BasicProperties;
ReadOnlyMemory body = result.Body;
string message = Encoding.UTF8.GetString(body.ToArray());
Console.WriteLine("接收的消息" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + ">" + message);
//确认已经处理消息,调用后会通知队列移除此消息
channel.BasicAck(result.DeliveryTag, false);
}
channel.Close();
conn.Close();
Console.ReadLine();
}
}
}
效果图: