【.NET】MSMQ 傳送與接收

  • 10792
  • 0

  近來的專案幾乎都有使用到 MSMQ,複習並記錄在 .NET 中使用 MSMQ 傳送與接收的部分。

  本篇以私有佇列為例。

1、用戶端存取名稱

  訊息佇列所參考的佇列位置,主要有兩種寫法。

1.1 使用伺服器名稱
var queuePath = @"FormatName:DIRECT=OS:[伺服器名稱]\private$\[佇列名稱]";

  若使用本機訊息佇列時,可以省略如下。

var queuePath = @".\private$\[佇列名稱]";
1.2 使用 IP 位址
var queuePath = @"FormatName:DIRECT=TCP:[IP 位址]\private$\[佇列名稱]";

2、傳送與接收

  在命名空間 System.Messaging 下的 MessageQueue 類別,是 .NET 提供控制與存取 Message Queue 伺服器訊息佇列的類別。

  使用類別中的方法 Send 與 Receive 方法來傳送與接收訊息主體物件。

  Receive 時需要先給定 Formatter 屬性,從訊息主體將物件還原序列化的格式子。

  訊息佇列在建立時分為交易式與非交易式,在 .NET 中兩種寫法略有不同,差別在於使用 MessageQueueTransaction 包覆傳送與接收。

Receive 可以使用無參數方法,加入 timeout 的目的在於當沒有訊息時,程式不會停滯。
2.1 非交易式
using Model;
using Service.Protocol;
using System;
using System.Messaging;

namespace Service
{
    public sealed class NonTransactionalQueueService : IQueueService
    {
        private readonly MessageQueue messageQueue;

        public NonTransactionalQueueService(string queuePath)
        {
            this.messageQueue = new MessageQueue(queuePath);
        }

        public void Send(Student student)
        {
            this.messageQueue.Send(student);
        }

        public Student Receive(TimeSpan timeout)
        {
            this.messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Student), });

            var message = this.messageQueue.Receive(timeout);

            return (Student)message.Body;
        }
    }
}
2.2 交易式
using Model;
using Service.Protocol;
using System;
using System.Messaging;

namespace Service
{
    public sealed class TransactionalQueueService : IQueueService
    {
        private readonly MessageQueue messageQueue;
        private readonly MessageQueueTransaction transaction;

        public TransactionalQueueService(string queuePath)
        {
            this.messageQueue = new MessageQueue(queuePath);

            this.transaction = new MessageQueueTransaction();
        }

        public void Send(Student student)
        {
            this.transaction.Begin();

            this.messageQueue.Send(student, this.transaction);

            this.transaction.Commit();
        }

        public Student Receive(TimeSpan timeout)
        {
            this.messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Student), });

            this.transaction.Begin();

            var message = this.messageQueue.Receive(timeout, this.transaction);

            this.transaction.Commit();

            return (Student)message.Body;
        }
    }
}

嘗試將自己的理解寫成文字紀錄,資料來源均來自於網路。

如有理解錯誤、引用錯誤或侵權,請多加指正與告知,讓我有更多的進步與改進的空間,謝謝!