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

.NET Compact Framework 進程間通信 (IPC) 實戰:MSMQ 消息隊列開發全解析

     編輯:關於.NET

Windows CE / Mobile 設備進程間通信 (IPC) 主流方案:**MSMQ (Microsoft Message Queuing)** 支持離線存轉、事務性、跨網絡路由,是移動場景下最可靠選擇。本文詳解 CF.NET 下 `System.Messaging` 開發:隊列創建、Formatter 配置、異步接收、請求-響應模式、發布-訂閱模式完整代碼。

核心類與配置

  • MessageQueue:隊列操作入口。
  • XmlMessageFormatter:序列化器,需指定允許類型數組 `new Type[] { typeof(string), typeof(int) }`。
  • 隊列路徑:私有隊列 `.\Private$\QueueName`,公共隊列 `MachineName\QueueName`。
  • 異步模式:`BeginReceive()` + `ReceiveCompleted` 事件 + `EndReceive()` 循環。

服務端:隊列初始化與監聽

public class MqService
{
    private const string QueuePath = @".\Private$\MQServiceQueue$";
    private MessageQueue _queue;

    public void Init()
    {
        if (!MessageQueue.Exists(QueuePath))
            _queue = MessageQueue.Create(QueuePath);
        else
            _queue = new MessageQueue(QueuePath);

        _queue.Formatter = new XmlMessageFormatter(new[] { typeof(string) });
        _queue.ReceiveCompleted += OnReceiveCompleted;
        _queue.BeginReceive(); // 進入異步接收循環
    }

    private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
    {
        try
        {
            var mq = (MessageQueue)sender;
            var msg = mq.EndReceive(e.AsyncResult); // 結束本次接收

            // 處理業務邏輯
            if (msg.Body is string cmd)
            {
                if (cmd == "mq_request_1")
                    msg.ResponseQueue?.Send("mq_response_1");
                else if (cmd == "mq_request_2")
                    msg.ResponseQueue?.Send(true);
            }
        }
        catch (MessageQueueException ex) { /* 日誌 */ }
        finally
        {
            // 關鍵:重新進入下一次接收
            _queue.BeginReceive();
        }
    }
}

客戶端:請求-響應模式

public class MqClient
{
    private const string ServicePath = @".\Private$\MQServiceQueue$";
    private const string ClientPath = @".\Private$\MQClientQueue$";
    private MessageQueue _svcQueue, _cliQueue;

    public void Init()
    {
        _svcQueue = new MessageQueue(ServicePath);
        if (!MessageQueue.Exists(ClientPath))
            _cliQueue = MessageQueue.Create(ClientPath);
        else
            _cliQueue = new MessageQueue(ClientPath);

        _cliQueue.Formatter = new XmlMessageFormatter(new[] { typeof(string), typeof(bool) });
        _cliQueue.ReceiveCompleted += OnClientReceive;
        _cliQueue.BeginReceive();
    }

    public void SendRequest()
    {
        var msg = new Message("mq_request_1") { ResponseQueue = _cliQueue };
        _cliQueue.Purge(); // 清空舊響應
        _svcQueue.Send(msg);

        // 同步等待響應 (含超時)
        var resp = _cliQueue.Receive(TimeSpan.FromSeconds(4));
        Console.WriteLine($"Response: {resp.Body}");
    }

    private void OnClientReceive(object sender, ReceiveCompletedEventArgs e)
    {
        // 異步響應處理邏輯 (如更新 UI)
        _cliQueue.BeginReceive();
    }
}

發布-訂閱模式 (Observer 跨進程)

// 服務端維護訂閱者字典
private Dictionary<string, MessageQueue> _subscribers = new Dictionary<string, MessageQueue>();

private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
    var msg = _queue.EndReceive(e.AsyncResult);
    if (msg.Body is string cmd)
    {
        if (cmd == "mq_register_1")
            _subscribers[msg.Label] = msg.ResponseQueue; // Label 作為訂閱者標識
        else if (cmd == "mq_unregister_1")
        {
            _subscribers[msg.Label]?.Purge();
            _subscribers.Remove(msg.Label);
        }
        else if (cmd == "mq_notify_all")
            NotifyAll(msg.Body.ToString());
    }
    _queue.BeginReceive();
}

private void NotifyAll(string payload)
{
    foreach (var q in _subscribers.Values)
        q.Send(payload);
}

客戶端發送 `mq_register_1` (Label=client1, ResponseQueue=本地隊列) 訂閱,服務端廣播遍歷字典 `Send`。

關鍵最佳實踐

  1. Formatter 類型完整聲明:漏類型會導致反序列化失敗。
  2. 異步循環必須 `BeginReceive` 遞歸:否則只能接收一條消息。
  3. ResponseQueue 傳遞:請求方創建專用響應隊列,避免服務隊列雙向混亂。
  4. 事務性隊列:`MessageQueue.Create(path, true)` 啟用事務,保證發送/接收原子性。
  5. 設備端安裝 MSMQ 服務:CE 設備需安裝 `MSMQ.cab` (隨 Platform Builder 或單獨下載)。

適用場景總結

模式適用場景
請求-響應設備與後台服務同步調用、命令下發確認
發布-訂閱實時通知、價格推送、狀態廣播、多設備協同
離線存轉網絡斷續環境下數據採集、日志上傳

MSMQ 將 Observer 模式擴展到進程邊界之外,是移動設備可靠 IPC 的基石。

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