首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 操作 MSMQ (Microsoft Message Queue) 完整範例

     編輯:關於VC++

前言

MSMQ (Microsoft Message Queuing) 提供可靠、非同步、跨機器的訊息傳遞基礎設施。本文示範使用 VC++ #import 匯入 MSMQ Type Library,透過 COM 介面 (IMSMQQueueInfo, IMSMQQueue, IMSMQMessage) 實現:建立佇列 (公用/私有)、發送訊息、接收訊息 (含期刊佇列)。

必要標頭與初始化


#import "mqoa.tlb" no_namespace // MSMQ Type Library
// 或 #import "C:\\Windows\\System32\\mqoa.tlb"

#include 

// 介面指標
IMSMQQueueInfoPtr qInfo;   // 佇列資訊 (建立/開啟)
IMSMQQueuePtr     qDest;   // 開啟後的佇列 (發送/接收)
IMSMQMessagePtr   qMsg;    // 訊息物件

// COM 初始化
CoInitialize(NULL);
try {
    qInfo.CreateInstance("MSMQ.MSMQQueueInfo");
    qMsg.CreateInstance("MSMQ.MSMQMessage");
    // 取得電腦名作為佇列路徑基礎
    TCHAR szName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
    GetComputerName(szName, &dwSize);
    m_strServer = szName; // 顯示於介面
} catch (_com_error& e) {
    MessageBox(_T("MSMQ 初始化失敗"), _T("錯誤"), MB_ICONERROR);
}

建立佇列


// 路徑格式:
// 私有佇列: .\\Private$\\MyQueue  (本機) / machinename\\Private$\\MyQueue (遠端)
// 公用佇列: .\\MyQueue           (需 AD 整合)

CString path = _T(".\\Private$\\MyTestQueue"); // 私有佇列
qInfo->PathName = path.AllocSysString();
qInfo->Label = _T("My Test Queue").AllocSysString();

// 格式名稱 (直接開啟用)
CString fmt = _T("DIRECT=OS:") + path;
qInfo->FormatName = fmt.AllocSysString();

// 建立
qInfo->Create();
// 啟用期刊 (記錄已送達/已接收訊息副本)
qInfo->Journal = VARIANT_TRUE;
qInfo->Update();
qInfo->Refresh();

發送訊息


try {
    // 開啟發送權限
    qDest = qInfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE);

    qMsg->Label = _T("Test Message").AllocSysString();

    VARIANT vBody; VariantInit(&vBody);
    vBody.vt = VT_BSTR;
    vBody.bstrVal = _T("Hello MSMQ!").AllocSysString();
    qMsg->put_Body(vBody);
    VariantClear(&vBody);

    qMsg->Send(qDest); // 同步發送
    qDest->Close();
} catch (_com_error& e) {
    MessageBox(_T("發送失敗"), _T("錯誤"), MB_ICONERROR);
}

接收訊息 (含期刊)


try {
    IMSMQQueueInfoPtr qRead; qRead.CreateInstance("MSMQ.MSMQQueueInfo");
    qRead->PathName = path.AllocSysString();
    CString fmt = _T("DIRECT=OS:") + path;
    if (bReadJournal) fmt += _T(";Journal"); // 讀取期刊佇列
    qRead->FormatName = fmt.AllocSysString();

    qDest = qRead->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);

    // 同步接收 (逾時參數 vtReceiveTimeout)
    VARIANT vtMissing; VariantInit(&vtMissing); vtMissing.vt = VT_ERROR; vtMissing.scode = DISP_E_PARAMNOTFOUND;
    VARIANT vtTimeout; VariantInit(&vtTimeout); vtTimeout.vt = VT_I4; vtTimeout.lVal = 5000; // 5秒

    qMsg = qDest->Receive(&vtMissing, &vtMissing, &vtMissing, &vtTimeout);
    if (qMsg == NULL) return; // 逾時無訊息

    _bstr_t label = qMsg->GetLabel();
    _variant_t body = qMsg->GetBody();
    m_strLabel = (LPCSTR)label;
    m_strBody  = (LPCSTR)(_bstr_t)body; // VT_BSTR 轉換

    UpdateData(FALSE); // 顯示到介面
    qDest->Close();
} catch (_com_error& e) {
    MessageBox(_T("接收失敗"), _T("錯誤"), MB_ICONERROR);
}

關鍵常數

常數值說明
MQ_SEND_ACCESS2發送存取
MQ_RECEIVE_ACCESS1接收存取
MQ_DENY_NONE0共享模式
DIRECT=OS:-格式名稱前綴,繞過 AD 查詢,直接開啟
;Journal-格式名稱後綴,開啟期刊佇列

部署需求

  • Windows 2000 / XP / Server 2003 內建 MSMQ (需在「新增/移除 Windows 元件」啟用)。
  • 工作群組模式僅支援私有佇列 (Private$);公用佇列需 Active Directory 整合 (網域環境)。
  • 防火牆需開放 TCP 1801 (MSMQ RPC) 及動態 RPC 埠範圍。
  • 遠端發送需目標機器 MSMQ 服務啟動且可解析電腦名/IP。

進階主題

  • 交易式訊息:IMSMQTransaction / IMSMQTransactionDispenser 保證完全一次 (Exactly Once) 投遞。
  • 非同步接收:BeginReceive/EndReceive 或事件 ReceiveCompleted 避免阻塞 UI 執行緒。
  • 訊息優先權/存活時間:qMsg->Priority, qMsg->TimeToBeReceived。
  • .NET System.Messaging:Managed 代碼建議直接使用 System.Messaging.MessageQueue,互通相容。

完整測試專案 (對話框介面,含建立/發送/接收/期刊切換) 可下載,VC6.0/VS.NET 編譯通過。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved