# 以 MQTT RabbitMQ 服務安裝在 docker 並搭配 .NET 6 進行實作發佈與訂閱 [toc] ![](https://hackmd.io/_uploads/H1deCjTa3.png) ## 安裝 RabbitMQ on Docker for Windows ![](https://hackmd.io/_uploads/S1qs6ja6h.png) [docker hub rabbitmq](https://hub.docker.com/_/rabbitmq) 1. 輸入 pull 指令下載 image `$ docker pull rabbitmq` 2. 建立 Container `$ docker run -d --hostname my-rabbit --name rock-rabbit rabbitmq:3` `$ docker run -d --name rock-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:management` > 預設 Port:5672 > --name rock-rabbit 表示將 Container 名稱設定為 rock-rabbit > rabbitmq:3 表示使用 rabbitmq tag 等於 3 的版本來建 Container 3. 設置預設用戶和密碼(請參考 docker 官方文件) > 預設使用者名稱和密碼都是 `guest` 4. 進入管理網站 > http://127.0.0.1:15672/ ![](https://hackmd.io/_uploads/r1IQQhTan.png) 登入成功 ![](https://hackmd.io/_uploads/r1347naan.png) > 當然你也可以綁定本機某一個 Port 號,來對應 15672 Container(請參考 docker 官網) ## 建立 Publisher 發佈者和 Consumer 訂閱者的帳號與密碼 ![](https://hackmd.io/_uploads/BJX3D0TT2.png) ![](https://hackmd.io/_uploads/SkCedA6ph.png) ![](https://hackmd.io/_uploads/ByhCDApp3.png) ## 建立訊息通道 ![](https://hackmd.io/_uploads/B1pNe066h.png) ![](https://hackmd.io/_uploads/H1jwxAaa2.png) # 撰寫一個 RabbitMQ 的 .NET 範例 ## 安裝套件 RabbitMQ.Client ![](https://hackmd.io/_uploads/B1_QD3p6h.png) ## 程式範例 ### Publisher 發佈者程式 ```csharp= internal class Program { static readonly string queueName = "stocktick"; static void Main(string[] args) //傳送端代碼 //創建連線工廠(ConnectionFactory)物件:這個物件用於設定與 RabbitMQ 伺服器的連線參數,包括使用者名稱、密碼、虛擬主機、主機名稱和埠號等。 ConnectionFactory factory = new ConnectionFactory(); factory.UserName = "send"; factory.Password = "send"; factory.VirtualHost = "/"; factory.HostName = "localhost"; factory.Port = 5672; // AmqpTcpEndpoint.UseDefaultPort; //創建連線(IConnection)物件:使用連線工廠創建一個連線至 RabbitMQ 伺服器。 IConnection connection = factory.CreateConnection(); int i = 0; //創建通道(IModel)物件:使用連線創建一個通道,通道用於執行 RabbitMQ 的各種操作,如隊列宣告、訊息發佈等。 using (var channel = connection.CreateModel()) { //宣告隊列:使用通道的 QueueDeclare 方法宣告一個隊列,指定隊列的名稱(queue)、是否持久化(durable)、是否獨佔(exclusive)、是否自動刪除(autoDelete)、和額外的參數(arguments)。 channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); while (i < 5) { string message = "Hello World! " + i; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: queueName, basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); Thread.Sleep(1000); i++; } } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } ``` ### Consumer 訂閱者程式 ```csharp= internal class Program { static readonly string queueName = "stocktick"; static void Main(string[] args) { Task threadTask = Task.Run(() => t1()); //threadTask.Wait(); // 等待任務完成 Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } static bool isQuitThread = false; private static void t1() { //建立接收者連線資訊 ConnectionFactory factory = new ConnectionFactory(); factory.UserName = "receive"; factory.Password = "receive"; factory.VirtualHost = "/"; factory.HostName = "localhost"; factory.Port = 5672;//AmqpTcpEndpoint.UseDefaultPort; IConnection connection = factory.CreateConnection(); //產生通道 using var channel = connection.CreateModel(); //宣告隊列:使用通道的 QueueDeclare 方法宣告一個隊列,指定隊列的名稱(queue)、是否持久化(durable)、是否獨佔(exclusive)、是否自動刪除(autoDelete)、和額外的參數(arguments)。 channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); Console.WriteLine(" [*] Waiting for messages."); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); //讓程式不要直接結束 while (isQuitThread) ; Debug.WriteLine("thread is quit!!"); } } ``` # 支援的程式語言 https://www.rabbitmq.com/devtools.html # 參考資料 [.NET/C# Client API Guide](https://www.rabbitmq.com/dotnet-api-guide.html) [MQTT教學(一):認識MQTT](https://swf.com.tw/?p=1002) [【RabbitMQ】五分鐘輕鬆了解 RabbitMQ 運作](https://zamhuang.medium.com/rabbitmq-%E4%BA%94%E5%88%86%E9%90%98%E8%BC%95%E9%AC%86%E4%BA%86%E8%A7%A3-rabbitmq-%E9%81%8B%E4%BD%9C-fcaecbaa69d4) [用 Docker 玩 RabbitMQ](https://hackmd.io/@SuFrank/rJ5Tgyb6q) ###### tags: `MQTT` `RabbitMQ`