1. 程式人生 > >C# Queue與RabbitMQ的愛恨情仇(文末附原始碼):Q與MQ訊息佇列簡單應用(二)

C# Queue與RabbitMQ的愛恨情仇(文末附原始碼):Q與MQ訊息佇列簡單應用(二)

上一章我們講了佇列( Queue),這一章我們講Message Queue訊息佇列,簡稱MQ。

定義:

  MQ是MessageQueue,訊息佇列的簡稱(是流行的開源訊息佇列系統,利用erlang語言開發)。MQ是一種應用程式對應用程式的通訊方法。

應用程式通過讀寫入隊和出隊的訊息來通訊,無需專用連線來連結它們。

訊息傳遞是程式之間通過在訊息中傳送資料進行通訊,而不是通過直接呼叫彼此來通訊,一般應用於遠端過程呼叫的技術。

 排隊指的是應用程式通過佇列來通訊。應用佇列避免接收和傳送資料的同時進行。

特點:

  MQ是消費者-生產者模型的代表。一端往訊息佇列中寫入訊息,另一端可以讀取或者訂閱佇列中的訊息。

MQ遵循的是AMQP協議(高階訊息佇列協議:使得遵從該規範的客戶端應用和訊息中介軟體伺服器的全功能互操作成為可能)的具體實現和產品。

應用:

  在使用MQ時,我們不需要實時的返回資訊。獲取資訊和返回資訊進行非同步處理。

例如:在專案中,我們需要從汽車系統中利用CAN匯流排實時的獲取汽車的相關資訊,但是沒有必要給汽車返回資訊。

如,獲取汽車的輪胎氣壓,但是我們不需要給汽車一個返回的資訊或結果。

    C#專案要利用RabbitMQ來獲取實時資料的話,需要先安裝客戶端的庫檔案:RabbitMQ.Client.dll,下面有提到。

備用下載路徑:

連結:https://pan.baidu.com/s/1zcQmPnBF7WcD8sqV4W54pw 

提取碼:6962 


寫在前面:

這個就需要安裝RabbitMQ服務、下載Erlang環境並安裝、引入RabbitMQ.client.dll動態庫。下面有官網可以下載相應的內容。

我這個使用windows 64位的,我這裡整理安裝程式在百度網盤,官網開啟Erlang很慢的去我百度網盤下載

連結:https://pan.baidu.com/s/1zcQmPnBF7WcD8sqV4W54pw
提取碼:6962 


 

安裝

需要安裝RabbitMQ服務:

官網下載地址:http://www.rabbitmq.com/download.html。

下載完成後一直點選下一步即可。

如果沒有Erlang環境會彈出下面的提示:

 

下載Erlang環境並安裝,安裝時一直點下一步即可

地址:http://www.erlang.org/downloads

如果開啟網頁慢或者打不開的,去下載我整理也行,不過我的是windows 64的。

連結:https://pan.baidu.com/s/1zcQmPnBF7WcD8sqV4W54pw 
提取碼:6962 

安裝完成後我們需要配置環境變數,如下:

點選【計算機】右鍵,屬性,高階系統設定,高階,環境變數,

新建一個系統變數。

輸入

變數名:ERLANG_HOME,

變數值:C:\Program Files\erl9.3

變數值是你剛剛安裝Erlang的路徑

 

 然後在找到環境變數裡面的Path,點選編輯,在變數值的最後面加上  ;%ERLANG_HOME%\bin;,記得有分號(英文分號)

 

 

安裝成功後會在服務中看到該服務。.

 

然後安裝RabbitMQ,也是一直點選下一步即可, 

到這裡後就準備工作做完了,接下來我們就編寫程式碼。

有的童鞋不知道為什麼需要安裝RabbitMQ服務和Erlang環境,我這裡簡單普及一下,詳細的請百度一下。

RabbitMQ是實現了高階訊息佇列協議(AMQP)的開源訊息代理軟體(亦稱面向訊息的中介軟體)。

RabbitMQ伺服器是用Erlang語言編寫的,而叢集和故障轉移是構建在開放電信平臺框架上的。

所有主要的程式語言均有與代理介面通訊的客戶端庫。

.


 程式碼例項:

為了講解效果更佳,我們新建兩個控制檯應用程式MessageQueueClient(生產者)和MessageQueueServer(消費者),

不要急著建立,看下面的程式碼依次建立。

生產者 :

新建控制檯應用程式MessageQueueClient,引用動態檔案庫RabbitMQ.Client.dll,可以去百度下載一個,上面的網盤路徑裡面有。

入隊程式碼編寫:

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MessageQueueClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //生產者
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1";
            //預設埠
            factory.Port = 5672;
            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    //在MQ上定義一個持久化佇列,如果名稱相同不會重複建立
                    channel.QueueDeclare("MyRabbitMQ", true, false, false, null);
                    while (true)
                    {
                        string message = string.Format("{0}", Console.ReadLine());  //Console.ReadLine()為控制檯輸入的內容,我們可以用其他方式獲取
                        byte[] buffer = Encoding.UTF8.GetBytes(message);
                        IBasicProperties properties = channel.CreateBasicProperties();  
                        properties.DeliveryMode = 2;
                        channel.BasicPublish("", "MyRabbitMQ", properties, buffer);  //入隊
                        Console.WriteLine("入隊成功:" + message);
                    }
                }
            }
        }
    }
}

控制檯入隊操作,控制檯這一步可以結合實際程式碼需求進行入隊。

這裡就入隊成功了,接下來我們出隊,也就是讀取資料,這裡和readis有點像,我們之前安裝的RabbitMQ服務就是在這裡用到了。

 

生產者 :

新建控制檯應用程式MessageQueueServer,引用動態檔案庫RabbitMQ.Client.dll,可以去百度下載一個,上面的網盤路徑裡面有。

出隊程式碼編寫:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MessageQueueServer
{
    class Program
    {
        static void Main(string[] args)
        {
            //消費者
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1";
            //預設埠
            factory.Port = 5672;
            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    //在MQ上定義一個持久化佇列,如果名稱相同不會重複建立
                    channel.QueueDeclare("MyRabbitMQ", true, false, false, null);

                    //輸入1,那如果接收一個訊息,但是沒有應答,則客戶端不會收到下一個訊息
                    channel.BasicQos(0, 1, false);

                    Console.WriteLine("Listening...");

                    //在佇列上定義一個消費者
                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    //消費佇列,並設定應答模式為程式主動應答
                    channel.BasicConsume("MyRabbitMQ", false, consumer);

                    while (true)
                    {
                        //阻塞函式,獲取佇列中的訊息
                        BasicDeliverEventArgs ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
                        byte[] bytes = ea.Body;
                        string str = Encoding.UTF8.GetString(bytes);

                        Console.WriteLine("讀取佇列訊息:" + str.ToString());
                        //回覆確認
                        channel.BasicAck(ea.DeliveryTag, false);
                    }
                }
            }
        }
    }
}

執行程式碼,讀取佇列裡面的內容,遵循先入先出原則。

這樣佇列的資料就讀取到了。

 

總結:

這是一個簡單的訊息佇列的應用,寫的比較粗淺,具體需要結合實際應用專案編寫。

另外感謝大家的支援^_^