如何获取队列消息类型

时间:2017-04-13 09:48:24

标签: azure queue azure-storage message-queue azure-storage-queues

我正在使用Azure存储队列,我想编写一些检索所有队列的代码,然后找到一个可以处理此队列中的消息的处理程序。为此,我定义了一个这样的界面:

public interface IHandler<T>

我有多个此接口的实现,例如:IHandler<CreateAccount>IHandler<CreateOrder>。我为每种消息类型使用1个队列,因此CreateAccount消息将进入create-account-queue

如何将它们连接起来?为了找到消息的正确Handler类,我首先需要知道消息类型,但似乎CloudQueueMessage个对象不包含该信息。

2 个答案:

答案 0 :(得分:2)

不是您问题的答案,但我将分享我们如何在我们的应用程序中处理完全相同的情况。

在我们的应用程序中,我们会像您一样发送不同类型的消息,并在后台进程中处理这些消息。

我们正在做的是在邮件正文中包含邮件类型。所以我们的信息通常如下:

        message: {
          type: 'Type Of Message',
          contents: {
            //Message contents
          }
        }

一个关键的区别是所有消息都在一个队列中(而不是在你的情况下是不同的队列)。接收方(后台进程)只轮询一个队列,获取消息并相应地识别该消息的消息类型和呼叫处理程序。

答案 1 :(得分:2)

您可以将元数据与每个队列相关联。由于您提到每个消息类型使用一个队列,因此可以将处理程序名称放在每个队列的元数据中。然后,您可以枚举所有队列并获取每个队列的元数据,以告诉您应该使用哪种类型的处理程序。这是一款快速控制台应用,可以展示我认为您所要求的内容:

using System;
using System.Collections.Generic;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue; 

namespace QueueDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //get a ref to our account.
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse("UseDevelopmentStorage=true;");
            CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient();

            //create our queues and add metadata showing what type of class each queue contains. 
            CloudQueue queue1 = cloudQueueClient.GetQueueReference("queue1"); 
            queue1.Metadata.Add("classtype", "classtype1");
            queue1.CreateIfNotExists();

            CloudQueue queue2 = cloudQueueClient.GetQueueReference("queue2");
            queue2.Metadata.Add("classtype", "classtype2");
            queue2.CreateIfNotExists();

            //enumerate our queues in a storage account and look at their metadata...
            QueueContinuationToken token = null;
            List<CloudQueue> cloudQueueList = new List<CloudQueue>();
            List<string> queueNames = new List<string>();

            do
            {
                QueueResultSegment segment = cloudQueueClient.ListQueuesSegmented(token);
                token = segment.ContinuationToken;
                cloudQueueList.AddRange(segment.Results);
            }
            while (token != null);

            try
            {
                foreach (CloudQueue cloudQ in cloudQueueList)
                {
                    //call this, or else your metadata won't be included for the queue. 
                    cloudQ.FetchAttributes(); 
                    Console.WriteLine("Cloud Queue name = {0}, class type = {1}", cloudQ.Name, cloudQ.Metadata["classtype"]);
                    queueNames.Add(cloudQ.Name);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception thrown listing queues: " + ex.Message);
                throw;
            }

            //clean up after ourselves and delete queues. 
            foreach (string oneQueueName in queueNames)
            {
                CloudQueue cloudQueue = cloudQueueClient.GetQueueReference(oneQueueName);
                cloudQueue.DeleteIfExists();
            }
            Console.ReadKey(); 
        }
    }
}

然而,可能更容易继承QueueMessage,然后将每个消息出列并识别您当前正在查看的子类,然后将其传递给正确的处理程序。