RabbitMQ .NET訊息佇列使用入門(五)【RabbitMQ例子】
生產者
using RabbitMQ.Client;
using System;
using System.Text;
using RabbitMQHelper;
using System.Collections.Generic;
using RabbitMQ.Client.MessagePatterns;
using RabbitMQ.Client.Events;
using System.Diagnostics;
using System.Threading;
namespace RabbitMQServer
{
class Program
{
static void Main(string[] args)
{
//建立返回一個新的頻道
using (var channel = RabbitMqHelper.GetConnection().CreateModel())
{
channel.QueueDeclare("test1", true, false, false, null);
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
for (var i = 0; i < 10000; i++)
{
try
{
channel.BasicPublish(string.Empty, "test1", properties, Encoding.UTF8.GetBytes($"這是{i}個訊息"));
Thread.Sleep(1000);
Console.WriteLine($"釋出訊息 {i}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
i--;
}
}
}
}
#region 懶佇列
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //宣告一個懶佇列
// channel.QueueDeclare("lazyqueue", true, false, false, new Dictionary<string, object>
// {
// { "x-queue-mode","lazy"}
// });
// for (var i = 0; i < 10000; i++)
// {
// channel.BasicPublish(string.Empty, "testqueue", null, Encoding.UTF8.GetBytes($"這是{i}個訊息"));
// }
// }
//}
#endregion
#region 確認機制
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// var watch = new Stopwatch();
// try
// {
// watch.Start();
// //channel.TxSelect();
// for (var i = 0; i < 10000; i++)
// {
// channel.BasicPublish(string.Empty, "testqueue", null, Encoding.UTF8.GetBytes($"這是{i}個訊息"));
// }
// //channel.TxCommit();
// //等待發布成功並返回釋出狀態
// // bool isok = channel.WaitForConfirms(new TimeSpan(1, 20, 30));
// watch.Stop();
// Console.WriteLine($"釋出一萬條沒有訊息確認,耗時{watch.ElapsedMilliseconds}毫秒");
// Console.ReadKey();
// }
// catch (Exception e)
// {
// //watch.Stop();
// //Console.WriteLine($"釋出一萬條使用了Confirm,耗時{watch.ElapsedMilliseconds}毫秒");
// //回退
// //channel.TxRollback();
// }
// }
//}
#endregion
#region 死信與優先順序別
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// channel.QueueDeclare("priorityQueue", true, false, false, new Dictionary<string, object> { { "x-max-priority", 5 } });
// var properties = channel.CreateBasicProperties();
// for (var i = 0; i < 6; i++)
// {
// properties.Priority = (byte)i;
// channel.BasicPublish(string.Empty, "priorityQueue", properties, Encoding.UTF8.GetBytes($"{i}級別的訊息"));
// }
// Console.ReadKey();
// }
//}
#endregion
#region dead letter
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// channel.BasicPublish(string.Empty, "testqueue", null, Encoding.UTF8.GetBytes("我五秒後就會消失"));
// Console.ReadKey();
// }
//}
#endregion
#region 宣告queue的引數們的作用
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //宣告一個queue,最大長度10,最大大小2048bytes
// channel.QueueDeclare("queue", true, false, false, new Dictionary<string, object>
// {
// { "x-max-length", 10 },
// { "x-max-length-bytes", 2048}
// });
// //宣告一個queue,queue五秒內而且未被任何形式的消費,則被刪除
// channel.QueueDeclare("queue", true, false, false, new Dictionary<string, object> { { "x-expires", 5000 } });
// //宣告一個queue,裡面的內容自發布起五秒後被刪除
// channel.QueueDeclare("messagettlqueue", true, false, false, new Dictionary<string, object> { { "x-message-ttl", 5000 } });
// var properties = channel.CreateBasicProperties();
// //設定過期時間
// properties.Expiration = "5000";
// channel.BasicPublish(null, "queue", properties, Encoding.UTF8.GetBytes("我五秒後就會消失"));
// ////建立一個rpc queue
// //channel.QueueDeclare("testQueue", true, true, false, null,);
// //using (var channel2 = RabbitMqHelper.GetConnection().CreateModel())
// //{
// // var consumer = new EventingBasicConsumer(channel2);
// // channel2.BasicGet("testQueue", true);
// //}
// //using (var connection = RabbitMqHelper.GetNewConnection())
// //using (var channel2 = connection.CreateModel())
// //{
// // var consumer = new EventingBasicConsumer(channel2);
// // channel2.BasicGet("testQueue", true);
// //}
// Console.ReadKey();
// }
//}
#endregion
#region rpc server
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //建立一個rpc queue
// channel.QueueDeclare("RpcQueue", true, false, false, null);
// SimpleRpcServer rpc = new SmsSimpleRpcServer(new Subscription(channel, "RpcQueue"));
// Console.WriteLine("服務端啟動成功");
// rpc.MainLoop();
// Console.ReadKey();
// }
//}
#endregion
#region topic 模式
//static void Main(string[] args)
//{
// var flag = true;
// while (flag)
// {
// Console.WriteLine("請輸入要釋出的訊息 key|msg。 或者按Ctrl+ C退出");
// var msg = Console.ReadLine();
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// var msgs = msg.Split('|');
// //釋出一個訊息
// var msgbody = Encoding.UTF8.GetBytes(msgs[1]);
// channel.BasicPublish("TopicExchange", routingKey: string.Empty, basicProperties: null, body: msgbody);
// Console.Write("釋出成功!");
// }
// }
// Console.ReadKey();
//}
#endregion
#region headers 模式
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //建立properties
// var properties = channel.CreateBasicProperties();
// //往內容的headers中塞入值
// properties.Headers = new Dictionary<string, object>()
// {
// {"user","admin" },
// {"pwd","123456" }
// };
// //釋出一個訊息
// var msg = Encoding.UTF8.GetBytes($"二狗子");
// channel.BasicPublish("headersExchange", routingKey: string.Empty, basicProperties: properties, body: msg);
// Console.Write("釋出成功!");
// }
// Console.ReadKey();
//}
#endregion
#region fanout模式
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //釋出一個訊息
// var msg = Encoding.UTF8.GetBytes($"二狗子");
// //不需要指定routingkey,指定了也沒用.因為交換機是fanout型別
// channel.BasicPublish("fanoutExchange", routingKey: string.Empty, basicProperties: null, body: msg);
// Console.Write("釋出成功!");
// }
// Console.ReadKey();
//}
#endregion
#region 日誌訊息釋出者 direct模式根據routngkey
//static void Main(string[] args)
//{
// //建立返回一個新的頻道
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //釋出一百個訊息
// for (var i = 0; i < 100; i++)
// {
// //對i進行求餘來決定日誌的級別
// var routingkey = i % 2 == 0 ? "info" : i % 3 == 0 ? "debug" : "error";
// var msg = Encoding.UTF8.GetBytes($"{i} :{routingkey}Message");
// channel.BasicPublish("LogExchange", routingKey: routingkey, basicProperties: null, body: msg);
// }
// Console.Write("釋出成功!");
// }
// Console.ReadKey();
//}
#endregion
#region 第一版與第二版 釋出多條訊息到交換機
//static void Main(string[] args)
//{
// //從工廠中拿到例項 本地host、使用者admin
// var factory = new ConnectionFactory()
// {
// UserName = "admin",
// Password = "admin",
// HostName = "localhost"
// };
// //建立連線
// using (var connection = factory.CreateConnection())
// //建立返回一個新的頻道
// using (var channel = connection.CreateModel())
// {
// //宣告一個direct型別的交換機
// channel.ExchangeDeclare("firstExchange", "direct", true, false, null);
// //宣告佇列
// channel.QueueDeclare("firstTest", true, false, false, null);
// //繫結佇列
// channel.QueueBind("firstTest", "firstExchange", "firstExchange_Demo_firstTest", null);
// //釋出一百個訊息
// for (var i = 0; i < 100; i++)
// {
// var msg = Encoding.UTF8.GetBytes($"{i} :Hello RabbitMQ");
// channel.BasicPublish("firstExchange", routingKey: "firstExchange_Demo_firstTest", basicProperties: null, body: msg);
// }
// Console.Write("釋出成功!");
// }
// Console.ReadKey();
//}
#endregion
}
/// <summary>
/// 傳送簡訊的Rpc
/// </summary>
public class SmsSimpleRpcServer : SimpleRpcServer
{
public SmsSimpleRpcServer(Subscription subscription) : base(subscription)
{
}
/// <summary>
/// 執行完成後進行h回撥
/// </summary>
/// <param name="isRedelivered"></param>
/// <param name="requestProperties"></param>
/// <param name="body"></param>
/// <param name="replyProperties"></param>
/// <returns></returns>
public override byte[] HandleSimpleCall(bool isRedelivered, IBasicProperties requestProperties, byte[] body, out IBasicProperties replyProperties)
{
replyProperties = null;
return Encoding.UTF8.GetBytes($"給{Encoding.UTF8.GetString(body)}傳送簡訊成功");
}
/// <summary>
/// 進行處理
/// </summary>
/// <param name="evt"></param>
public override void ProcessRequest(BasicDeliverEventArgs evt)
{
// todo.....
base.ProcessRequest(evt);
}
}
}
消費者
using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQHelper;
using System.Collections.Generic;
using RabbitMQ.Client.MessagePatterns;
namespace RabbitMQConsumer
{
class Program
{
static void Main(string[] args)
{
using (var channel = RabbitMqHelper.GetConnection().CreateModel())
{
//宣告佇列
channel.QueueDeclare("testqueue", true, false, false, null);
var consumer = new EventingBasicConsumer(channel);
var result = channel.BasicGet("testqueue", false);
Console.WriteLine(Encoding.UTF8.GetString(result.Body));
//扔掉訊息
//channel.BasicReject(result.DeliveryTag, false);
//退回訊息
channel.BasicReject(result.DeliveryTag, true);
//批量退回或刪除,中間的引數 是否批量 true是/false否 (也就是隻一條)
//channel.BasicNack(result.DeliveryTag, true, true);
////補發訊息 true退回到queue中/false只補發給當前的consumer
//channel.BasicRecover(true);
var result2 = channel.BasicGet("testqueue", false);
Console.WriteLine(Encoding.UTF8.GetString(result2.Body));
//consumer.Received += (sender, e) =>
//{
// Console.WriteLine(Encoding.UTF8.GetString(e.Body));
// //扔掉訊息
// channel.BasicReject(e.DeliveryTag, false);
// //再還給queue
// //channel.BasicReject(e.DeliveryTag, true);
//};
//不自動確認
channel.BasicConsume("testqueue", false, consumer);
Console.WriteLine("consumer啟動成功");
Console.ReadKey();
}
}
#region 死信
//static void Main(string[] args)
//{
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //宣告一個帶有死信功能功能的queue exchange: dlexchange queue: dlexqueue
// channel.QueueDeclare("testqueue", true, false, false, new Dictionary<string, object>
// {
// { "x-message-ttl",5000},
// { "x-dead-letter-exchange", "dlexchange" },
// { "x-dead-letter-routing-key", "dlexqueue"}
// });
// //負責死信的交換機
// channel.ExchangeDeclare("dlexchange", ExchangeType.Direct, true, false, null);
// channel.QueueDeclare("dlexqueue", true, false, false, null);
// channel.QueueBind("dlexqueue", "dlexchange", "dlexqueue", null);
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// Console.WriteLine(Encoding.UTF8.GetString(e.Body));
// };
// channel.BasicConsume("testqueue", true, consumer);
// Console.WriteLine("consumer啟動成功");
// Console.ReadKey();
// }
//}
#endregion
#region RPC客戶端
//static void Main(string[] args)
//{
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //建立client的rpc
// SimpleRpcClient client = new SimpleRpcClient(channel, new PublicationAddress(exchangeType: ExchangeType.Direct, exchangeName: string.Empty, routingKey: "RpcQueue"));
// bool flag = true;
// var sendmsg = "";
// while (flag)
// {
// Console.WriteLine("請輸入要傳送的訊息");
// sendmsg = Console.ReadLine();
// if (string.IsNullOrWhiteSpace(sendmsg))
// {
// Console.Write("請輸入訊息");
// continue;
// }
// var msg = client.Call(Encoding.UTF8.GetBytes(sendmsg));
// Console.WriteLine(Encoding.UTF8.GetString(msg));
// }
// Console.ReadKey();
// }
//}
#endregion
#region topic 模式
//static void Main(string[] args)
//{
// bool flag = true;
// var key = "";
// while (flag)
// {
// Console.WriteLine("請輸入路由正則 .代表一個字元 *代表零到多個字元");
// key = Console.ReadLine();
// if (string.IsNullOrWhiteSpace(key))
// {
// Console.Write("請輸入路由");
// continue;
// }
// else
// flag = false;
// }
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //根據宣告使用的佇列
// var QueueName = key + "Queue";
// //宣告交換機 headers模式
// channel.ExchangeDeclare("TopicExchange", ExchangeType.Topic, true, false);
// channel.QueueDeclare(QueueName, true, false, false, null);
// //進行繫結
// channel.QueueBind(QueueName, "TopicExchange", key, null);
// //建立consumbers
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// var msg = Encoding.UTF8.GetString(e.Body);
// Console.WriteLine($"{e.RoutingKey}:{msg}");
// };
// //進行消費
// channel.BasicConsume(QueueName, true, consumer);
// Console.ReadKey();
// }
//}
#endregion
#region headers exchange模式
//static void Main(string[] args)
//{
// bool flag = true;
// string pattern = "";
// while (flag)
// {
// Console.WriteLine("請選擇headers匹配模式 1(any)/2(all)");
// pattern = Console.ReadLine();
// if (pattern == "1" || pattern == "2")
// flag = false;
// else
// Console.Write("請做出正確的選擇");
// }
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //根據宣告使用的佇列
// var headersType = pattern == "1" ? "any" : "all";
// //宣告交換機 headers模式
// channel.ExchangeDeclare("headersExchange", ExchangeType.Headers, true, false);
// channel.QueueDeclare("headersQueue", true, false, false, null);
// //進行繫結
// channel.QueueBind("headersQueue", "headersExchange", string.Empty, new Dictionary<string, object>
// {
// //第一個匹配格式 ,第二與第三個則是匹配項
// { "x-match",headersType},
// { "user","admin"},
// { "pwd","123456"}
// });
// //建立consumbers
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// var msg = Encoding.UTF8.GetString(e.Body);
// Console.WriteLine($"{msg}");
// };
// //進行消費
// channel.BasicConsume("headersQueue", true, consumer);
// Console.ReadKey();
// }
//}
#endregion
#region fanout模式
//static void Main(string[] args)
//{
// bool flag = true;
// string pattern = "";
// while (flag)
// {
// Console.WriteLine("請選擇Ccnsumer模式 1(發簡訊)/2(發郵件)");
// pattern = Console.ReadLine();
// if (pattern == "1" || pattern == "2")
// flag = false;
// else
// Console.Write("請做出正確的選擇");
// }
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //宣告交換機 Fanout模式
// channel.ExchangeDeclare("fanoutExchange", ExchangeType.Fanout, true, false, null);
// //根據宣告使用的佇列
// var queueName = pattern == "1" ? "sms" : "emai";
// channel.QueueDeclare(queueName, true, false, false, null);
// //進行繫結
// channel.QueueBind(queueName, "fanoutExchange", string.Empty, null);
// //建立consumbers
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// var msg = Encoding.UTF8.GetString(e.Body);
// var action = (pattern == "1" ? "發簡訊" : "發郵件");
// Console.WriteLine($"給{msg}{action}");
// };
// //進行消費
// channel.BasicConsume(queueName, true, consumer);
// Console.ReadKey();
// }
//}
#endregion
#region 日誌訊息消費者 direct模式根據routingkey
//static void Main(string[] args)
//{
// bool flag = true;
// string level = "";
// while (flag)
// {
// Console.WriteLine("請指定要接收的訊息級別");
// level = Console.ReadLine();
// if (level == "info" || level == "error" || level == "debug")
// flag = false;
// else
// Console.Write("僅支援info、debug與error級別");
// }
// using (var channel = RabbitMqHelper.GetConnection().CreateModel())
// {
// //宣告交換機 direct模式
// channel.ExchangeDeclare("LogExchange", "direct", true, false, null);
// //根據宣告使用的佇列
// var queueName = level == "info" ? "Log_else" : level == "debug" ? "Log_else" : "Log_error";
// channel.QueueDeclare(queueName, true, false, false, null);
// //進行繫結
// channel.QueueBind(queueName, "LogExchange", level, null);
// //建立consumbers
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// var msg = Encoding.UTF8.GetString(e.Body);
// Console.WriteLine(msg);
// };
// //進行消費
// channel.BasicConsume(queueName, true, consumer);
// Console.ReadKey();
// }
//}
#endregion
#region 第一版與第二版簡單Demo、交換機佇列繫結
//static void Main(string[] args)
//{
// //consumber端
// var factory = new ConnectionFactory()
// {
// HostName = "localhost",
// UserName = "admin",
// Password = "admin"
// };
// using (var connection = factory.CreateConnection())
// using (var channel = connection.CreateModel())
// {
// //獲取訊息
// #region 第一版直接拉取
// //不再使用直接拉取的方式
// //var result = channel.BasicGet("firstTest", true);
// //var msg = Encoding.UTF8.GetString(result.Body);
// // Console.WriteLine(msg);
// #endregion
// //使用訂閱的方式
// //這裡的建立佇列,是為了防止 消費 在 生產 之前
// channel.QueueDeclare("firstTest", true, false, false, null);
// //繫結佇列
// channel.ExchangeDeclare("firstExchange", "direct", true, false, null);
// channel.QueueBind("firstTest", "firstExchange", "firstExchange_Demo_firstTest", null);
// var consumer = new EventingBasicConsumer(channel);
// consumer.Received += (sender, e) =>
// {
// var msg = Encoding.UTF8.GetString(e.Body);
// Console.WriteLine(msg);
// };
// //進行消費
// channel.BasicConsume("firstTest", true, consumer);
// Console.ReadKey();
// }
//}
#endregion
}
}
RabbitMqHelper.cs
using RabbitMQ.Client;
using System;
using System.Text;
namespace RabbitMQHelper
{
/// <summary>
/// RabbitMQ幫助類
/// </summary>
public class RabbitMqHelper
{
private static IConnection Connection;
/// <summary>
/// 獲取連線物件
/// </summary>
/// <returns></returns>
public static IConnection GetConnection()
{
if (Connection == null)
{
//從工廠中拿到例項 本地host、使用者admin
var factory = new ConnectionFactory()
{
HostName = "192.168.1.117",
UserName = "admin",
Password = "admin",
AutomaticRecoveryEnabled = true,
TopologyRecoveryEnabled = true,
Port = 25672
};
Connection = factory.CreateConnection();
return Connection;
}
return Connection;
}
public static IConnection GetNewConnection()
{
//從工廠中拿到例項 本地host、使用者admin
var factory = new ConnectionFactory()
{
HostName = "192.168.1.117",
UserName = "admin",
Password = "admin",
AutomaticRecoveryEnabled = true,
TopologyRecoveryEnabled = true,
Port = 25672
};
Connection = factory.CreateConnection();
return Connection;
}
}
}
相關文章
- RabbitMQ .NET訊息佇列使用入門(四)【RabbitMQ用法大全】MQ佇列
- RabbitMQ訊息佇列(五):Routing 訊息路由MQ佇列路由
- [訊息佇列]RabbitMQ佇列MQ
- RabbitMQ訊息佇列MQ佇列
- MQ訊息佇列_RabbitMQMQ佇列
- 訊息佇列之RabbitMQ佇列MQ
- rabbitmq訊息佇列原理MQ佇列
- RabbitMQ 訊息佇列之佇列模型MQ佇列模型
- SpringBoot:初探 RabbitMQ 訊息佇列Spring BootMQ佇列
- RabbitMQ 入門 - 工作佇列MQ佇列
- 訊息佇列的使用場景之RabbitMQ佇列MQ
- RabbitMQ學習系列二:.net 環境下 C#程式碼使用 RabbitMQ 訊息佇列MQC#佇列
- 入門RabbitMQ訊息佇列,看這篇文章就夠了MQ佇列
- RabbitMQ 訊息佇列之 Exchange TypesMQ佇列
- RabbitMQ訊息佇列(二):”Hello, World“MQ佇列
- Laravel5.6 整合 RabbitMQ 訊息佇列LaravelMQ佇列
- 什麼是Rabbitmq訊息佇列? (安裝Rabbitmq,透過Rabbitmq實現RPC全面瞭解,從入門到精通)MQ佇列RPC
- RabbitMQ訊息佇列(六):使用主題進行訊息分發MQ佇列
- RabbitMQ學習(三)之 “訊息佇列高階使用”MQ佇列
- 2018-06-14: Java 訊息佇列之 RabbitMQ 使用Java佇列MQ
- RabbitMQ訊息佇列-Centos7下安裝RabbitMQ3.6.1MQ佇列CentOS
- 【訊息佇列】RabbitMq-宣告佇列與交換機佇列MQ
- 【訊息佇列】RabbitMq-交換機模型佇列MQ模型
- RabbitMQ使用教程(五)如何保證佇列裡的訊息99.99%被消費?MQ佇列
- 訊息中介軟體RabbitMQ_RabbitMQ快速入門3MQ
- RabbitMQ訊息佇列(九):Publisher的訊息確認機制MQ佇列
- 訊息佇列Rabbitmq的交換器型別佇列MQ型別
- 萬字長文:從 C# 入門學會 RabbitMQ 訊息佇列程式設計C#MQ佇列程式設計
- RabbitMQ高階之訊息限流與延時佇列MQ佇列
- RabbitMQ,RocketMQ,Kafka 幾種訊息佇列的對比MQKafka佇列
- 架構設計之NodeJS操作訊息佇列RabbitMQ架構NodeJS佇列MQ
- RabbitMQ訊息佇列(三):任務分發機制MQ佇列
- lumen 8.0 使用 rabbitmq 佇列MQ佇列
- Java訊息佇列:RabbitMQ與Kafka的整合與應用Java佇列MQKafka
- 基於訊息佇列(RabbitMQ)實現延遲任務佇列MQ
- RabbitMQ訊息佇列(四):分發到多Consumer(Publish/Subscribe)MQ佇列
- RabbitMQ 入門(三)SpringAMQP訊息轉換器MQSpringGAM
- Springboot + rabbitMq佇列Spring BootMQ佇列