首先搭建RabbitMQ开发环境,不知道流程的自行百度。
搭建完成后默认访问地址为:http://localhost:15672 管理界面如下图所示:

公共类:
public class RequestMsg
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
public string Code { get; set; }
}
public class Constants
{
/// <summary>
/// Host地址
/// </summary>
public const string MqHost = "127.0.0.1";
/// <summary>
/// 端口号
/// </summary>
public const int MqPort = 5672;
/// <summary>
/// 用户名
/// </summary>
public const string UserName = "guest";
/// <summary>
/// 密码
/// </summary>
public const string Password = "guest";
}消息生产者控制台执行代码:
//建立RabbitMQ连接和通道
ConnectionFactory connectionFactory = new ConnectionFactory
{
HostName = "127.0.0.1",
Port = 5672,
UserName = "guest",
Password = "guest",
Protocol = Protocols.DefaultProtocol,
AutomaticRecoveryEnabled = true, //自动重连
RequestedFrameMax = UInt32.MaxValue,
RequestedHeartbeat = UInt16.MaxValue //心跳超时时间
};
try
{
using (var connection = connectionFactory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
//创建一个新的Direct模式的持久交换区 exchange持久化 SISOExchange表示Exchange名称 durable: true, autoDelete: false, arguments: null
channel.ExchangeDeclare("SISOExchange", ExchangeType.Direct, true, false, null);
//创建一个新的,持久的队列, 没有排他性,与不自动删除 queue持久化 durable: true, exclusive: false, autoDelete: false, arguments: null
channel.QueueDeclare("SISOqueue", true, false, false, null);
// 绑定队列到交换区 Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来. 如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的,如果exchange和queue两者之间有一个持久化,一个非持久化,则不允许建立绑定.
//注意:一旦创建了队列和交换机,就不能修改其标志了,例如,创建了一个non-durable的队列,然后想把它改变成durable的,唯一的办法就是删除这个队列然后重现创建。
//channel.queueBind("queue_name","exchange_name","route_key");
channel.QueueBind("SISOqueue", "SISOExchange", "optionalRoutingKey");
// 设置消息属性
var properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2; //消息是持久的,存在并不会受服务器重启影响 1是非持久化
//准备开始推送
//发布的消息可以是任何一个(可以被序列化的)字节数组,如序列化对象,一个实体的ID,或只是一个字符串
var encoding = new UTF8Encoding();
for (var i = 0; i < 10; i++)
{
var msg = string.Format("这是消息 #{0}--{1}?", i + 1,DateTime.Now.ToString());
var msgBytes = encoding.GetBytes(msg);
//var msgBytes = Encoding.UTF8.GetBytes(msg);
//RabbitMQ消息模型的核心思想就是,生产者不把消息直接发送给队列。实际上,生产者在很多情况下都不知道消息是否会被发送到一个队列中。取而代之的是,生产者将消息发送到交换区。交换区是一个非常简单的东西,它一端接受生产者的消息,另一端将他们推送到队列中。交换区必须要明确的指导如何处理它接受到的消息。是放到一个队列中,还是放到多个队列中,亦或是被丢弃。这些规则可以通过交换区的类型来定义。
//可用的交换区类型有:direct,topic,headers,fanout。
//Exchange:用于接收消息生产者发送的消息,有三种类型的exchange:direct, fanout,topic,不同类型实现了不同的路由算法;
//RoutingKey:是RabbitMQ实现路由分发到各个队列的规则,并结合Binging提供于Exchange使用将消息推送入队列;
//Queue:是消息队列,可以根据需要定义多个队列,设置队列的属性,比如:消息移除、消息缓存、回调机制等设置,实现与Consumer通信;
channel.BasicPublish("SISOExchange", "optionalRoutingKey", properties, msgBytes);
}
channel.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("消息发布!");
Console.ReadKey(true);消费者控制台代码:
// 建立RabbitMQ连接和通道 由ConnectionFactory创建,每个connection只与一个物理的Server进行连接,此连接是基于Socket进行连接的
ConnectionFactory connectionFactory = new ConnectionFactory
{
HostName = "127.0.0.1",
Port = 5672,
UserName = "guest",
Password = "guest",
Protocol = Protocols.AMQP_0_9_1,
RequestedFrameMax = UInt32.MaxValue,
RequestedHeartbeat = UInt16.MaxValue
};
using (var connection = connectionFactory.CreateConnection())
//连接通道 一个Connection可以有多个Channel
using (var channel = connection.CreateModel())
{
// 这指示通道不预取超过1个消息
channel.BasicQos(0, 1, false);
//创建一个新的,持久的交换区
channel.ExchangeDeclare("SISOExchange", ExchangeType.Direct, true, false, null);
//创建一个新的,持久的队列 sample-queue为队列名称
channel.QueueDeclare("sample-queue", true, false, false, null);
//绑定队列到交换区
channel.QueueBind("SISOqueue", "SISOExchange", "optionalRoutingKey");
using (var subscription = new Subscription(channel, "SISOqueue", false))
{
Console.WriteLine("等待消息...");
var encoding = new UTF8Encoding();
while (channel.IsOpen)
{
BasicDeliverEventArgs eventArgs;
var success = subscription.Next(2000, out eventArgs);
if (success == false) continue;
var msgBytes = eventArgs.Body;
var message = encoding.GetString(msgBytes);
Console.WriteLine(message);
channel.BasicAck(eventArgs.DeliveryTag, false);
}
}
}运行结果:

示例二:
消息生产者控制台代码: /*
try
{
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = Constants.MqHost;
factory.Port = Constants.MqPort;
factory.UserName = Constants.UserName;
factory.Password = Constants.Password;
using (IConnection conn = factory.CreateConnection())
{
using (IModel channel = conn.CreateModel())
{
channel.QueueDeclare("myFirstQueue", true, false, false, null);
while (true)
{
string customStr = Console.ReadLine();
RequestMsg requestMsg = new RequestMsg();
requestMsg.Name = string.Format("Name_{0}", customStr);
requestMsg.Code = string.Format("Code_{0}", customStr);
string jsonStr = JsonConvert.SerializeObject(requestMsg);
byte[] bytes = Encoding.UTF8.GetBytes(jsonStr);
//设置消息持久化
IBasicProperties properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2;
channel.BasicPublish("", "MyFirstQueue", properties, bytes);
//channel.BasicPublish("", "MyFirstQueue", null, bytes);
Console.WriteLine("消息已发送:" + requestMsg.ToString());
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
*/ 消息消费者控制台代码: /*
try
{
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = Constants.MqHost;
factory.Port = Constants.MqPort;
factory.UserName = Constants.UserName;
factory.Password = Constants.Password;
using (IConnection conn = factory.CreateConnection())
{
using (IModel channel = conn.CreateModel())
{
//在MQ上定义一个持久化队列,如果名称相同不会重复创建
channel.QueueDeclare("MyFirstQueue", true, false, false, null);
//输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息
channel.BasicQos(0, 1, false);
Console.WriteLine("Listening...");
//在队列上定义一个消费者
QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
//消费队列,并设置应答模式为程序主动应答
channel.BasicConsume("MyFirstQueue", false, consumer);
while (true)
{
//阻塞函数,获取队列中的消息
BasicDeliverEventArgs ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
byte[] bytes = ea.Body;
string str = Encoding.UTF8.GetString(bytes);
RequestMsg msg = JsonConvert.DeserializeObject<RequestMsg>(str);
Console.WriteLine("HandleMsg:" + msg.ToString());
//回复确认
channel.BasicAck(ea.DeliveryTag, false);
}
}
}
}
catch (Exception e1)
{
Console.WriteLine(e1.ToString());
}
Console.ReadLine();
*/

3431

被折叠的 条评论
为什么被折叠?



