RabbitMQ .NET訊息佇列使用入門(五)【RabbitMQ例子】

風靈使發表於2018-07-24

生產者

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;

        }
    }
}

相關文章