一 、MSMQ概述
MSMQ全稱MicroSoft Message Queue,微軟消息隊列,是在多個不同的應用之間實現相互通信的一種異步傳輸模式,相互通信的應用可以分布於同一台機器上,也可以分布於相連的網絡空間中的任一位置。它的實現原理是:消息的發送者把自己想要發送的信息放入一個容器中(我們稱之為Message),然后把它保存至一個系統公用空間的消息隊列(Message Queue)中;本地或者是異地的消息接收程序再從該隊列中取出發給它的消息進行處理。
消息Message是由通信的雙方所需要傳遞的信息。
隊列的類型主要包括一下幾種:
“公共隊列”在整個“消息隊列”網絡中復制,並且有可能由網絡連接的所有站點訪問。
“專用隊列”不在整個網絡中發布。相反,它們僅在所駐留的本地計算機上可用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。
“管理隊列”包含確認在給定“消息隊列”網絡中發送的消息回執的消息。指定希望 MessageQueue 組件使用的管理隊列(如果有的話)。
“響應隊列”包含目標應用程序接收到消息時返回給發送應用程序的響應消息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。
優點:穩定、消息優先級、脫機能力以及安全性,有保障的消息傳遞和執行許多業務處理的可靠的防故障機制。
缺點:MSMQ不適合於Client需要Server端實時交互情況.大量請求時候,響應延遲.
二 、安裝啟用服務
1. 控制面板 >> 程序 >> 打開或關閉Windows功能 >> Microsoft Message Queue(MSMQ)服務器,勾選消息隊列服務所有選項

2. 我的電腦 >> 管理 >> 服務和應用程序 >> 消息隊列 。出現消息隊列則說明安裝成功

三 、MSMQ編碼應用舉例
以下是幾個常用查詢代碼
請先添加using System.Messaging;命名空間
1. 查詢隊列是否存在,值得注意的是,當訪問遠端消息時MSMQ不支持MessageQueue.Exists(string )等方法,所以建議直接使用new MessageQueue(QueuePath)查詢
/// <summary> /// 查詢隊列是否存在 /// </summary> /// <returns></returns> public bool QueueExist() { bool queueExist = false; try { queueExist = MessageQueue.Exists(QueuePath); } catch//遠端訪問不支持exist,所有直接查詢 { queueExist = true; } return queueExist; }
2. 創建隊列,傳入存儲對象和注解標簽
/// <summary> /// 創建隊列 /// </summary> /// <param name="queueObj">發送到隊列的對象</param> /// <param name="queueLable">該發送隊列對象的標簽</param> public void CreateQueue(object queueObj, string queueLable = "") { try { using (MessageQueue queue = QueueExist() ? new MessageQueue(QueuePath) : MessageQueue.Create(QueuePath)) { queue.Label = queueLable; if (queue.CanWrite) { queue.Send(queueObj); } } } catch (Exception ex) { throw new Exception("Error to Create Queue!", ex); } }
3. 獲取隊列第一條數據,並刪除數據
/// <summary> /// 獲取隊列第一條數據,並刪除數據 /// </summary> /// <param name="queueTypes"></param> /// <returns></returns> public object ReceiveOneQueue(Type[] queueTypes) { object result = null; if (QueueExist()) { using (MessageQueue mq = new MessageQueue(QueuePath)) { try { // 設置消息隊列的格式化器 mq.Formatter = new XmlMessageFormatter(queueTypes); if (mq.CanRead) { Message oneMessage = mq.Receive(); // 獲得消息隊列中第一條消息 result = oneMessage.Body; } } catch (Exception ex) { throw new Exception("Error to query Queue!", ex); } } } return result; }
4. 獲取隊列第一條數據,但保留數據
/// <summary> /// 獲取隊列第一條數據,但保留數據 /// </summary> /// <param name="queueTypes"></param> /// <returns></returns> public object PeekOneQueue(Type[] queueTypes) { object result = null; if (QueueExist()) { using (MessageQueue mq = new MessageQueue(QueuePath)) { try { // 設置消息隊列的格式化器 mq.Formatter = new XmlMessageFormatter(queueTypes); if (mq.CanRead) { Message oneMessage = mq.Peek(); // 獲得消息隊列中第一條消息 result = oneMessage.Body; } } catch (Exception ex) { throw new Exception("Error to query Queue!", ex); } } } return result; }
5. 調用程序
//遠程連接請使用FormatName:DIRECT=ftp://222.10.xx.xx/msmq/Private$/msmqpath MSMQUtil.MSMQHelper msmqHelper = new MSMQUtil.MSMQHelper(@".\Private$\msmqpath"); msmqHelper.CreateQueue("first msmq", "first lable"); msmqHelper.CreateQueue(new msmqtestclass() { age = 25, name = "xieyang", contents = new List<string>() { "my leg", "my head" } }); var formater1 = new Type[] { typeof(string) }; object obj1 = msmqHelper.ReceiveOneQueue(formater1); var formater2 = new Type[] { typeof(msmqtestclass) }; object obj2 = msmqHelper.ReceiveOneQueue(formater2);
最常見錯誤: 當鏈接為遠程時,需要給everyone讀寫權限。
完整代碼
鏈接:https://pan.baidu.com/s/1lviQzuvGJFuXTqv4_7GmtA
提取碼:vvxy
參考:https://docs.microsoft.com/zh-cn/dotnet/api/system.messaging?view=netframework-4.7.2
https://www.cnblogs.com/zhili/p/MSMQ.html
