【.NET】MSMQ 傳送與接收

  • 10008
  • 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 伺服器訊息佇列的類別。

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

  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;
        }
    }
}

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

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