Working with Messages in Azure Storage Queues

This article details how to interact with messages within an Azure Storage Queue. Azure Queues are a service that allows you to store large numbers of messages that can be accessed from anywhere in the world via HTTP(S).

Note: Azure Queues are part of Azure Storage. For higher throughput and more advanced messaging scenarios, consider using Azure Service Bus Queues or Azure Event Hubs.

Message Structure

Each message in an Azure Queue can be up to 64 KB in size. The message content is typically a string, but can be any format (e.g., JSON, XML) that you can serialize to a string.

Common Operations

1. Adding a Message to a Queue (PutMessage)

To add a message, you send a PUT request to the queue's messages collection. The message content must be URL-encoded.

POST https://myaccount.queue.core.windows.net/myqueue/messages
    Content-Type: application/xml
    Authorization: SharedKey myaccount:somekey==
    Date: Mon, 27 Jul 2009 17:40:35 GMT
    Content-Length: 35

    messagetext
    

The response includes the message's `messageid`, `insertiontime`, `expirationtime`, `popreceipt`, and `nextvisibletime`.

2. Retrieving and Dequeuing Messages (GetMessages)

To retrieve messages, you send a GET request to the queue's messages collection. You can optionally specify the `numofmessages` (1-32) and `visibilitytimeout` parameters.

GET https://myaccount.queue.core.windows.net/myqueue/messages?numofmessages=5&visibilitytimeout=30
    Authorization: SharedKey myaccount:somekey==
    Date: Mon, 27 Jul 2009 17:40:35 GMT
    

Messages are returned in a collection. Each message object contains:

Tip: The `visibilitytimeout` parameter is crucial for distributed processing. It makes the message invisible to other clients for a specified duration, preventing multiple workers from processing the same message concurrently.

3. Updating a Message (UpdateMessage)

After processing a message, you might need to update its visibility timeout or re-encode it. This is done with a PUT request.

PUT https://myaccount.queue.core.windows.net/myqueue/messages/message-id?popreceipt=1c9f7a25-742b-466a-918b-423b856b27f2&visibilitytimeout=120
    Content-Type: application/xml
    Authorization: SharedKey myaccount:somekey==
    Date: Mon, 27 Jul 2009 17:40:35 GMT
    Content-Length: 0
    

4. Deleting a Message (DeleteMessage)

Once a message has been successfully processed, it must be explicitly deleted using its `messageid` and `popreceipt`.

DELETE https://myaccount.queue.core.windows.net/myqueue/messages/message-id?popreceipt=1c9f7a25-742b-466a-918b-423b856b27f2
    Authorization: SharedKey myaccount:somekey==
    Date: Mon, 27 Jul 2009 17:40:35 GMT
    
Warning: If a message is not deleted after its visibility timeout expires, it will become visible again and can be dequeued by another client. Ensure your processing logic includes proper error handling and deletion.

Example: Using Azure SDK for .NET

Here's a simplified example of how you might work with messages using the Azure Storage SDK for .NET.


using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;
using System;
using System.Threading.Tasks;

public class QueueMessageExample
{
    public static async Task RunAsync()
    {
        string connectionString = "YOUR_AZURE_STORAGE_CONNECTION_STRING";
        string queueName = "my-sample-queue";

        // Get a reference to the queue
        QueueClient queueClient = new QueueClient(connectionString, queueName);

        // Create the queue if it doesn't exist
        await queueClient.CreateIfNotExistsAsync();

        // --- Add a message ---
        string messageText = "{\"orderId\": \"12345\", \"item\": \"widget\"}";
        await queueClient.SendMessageAsync(messageText);
        Console.WriteLine($"Message sent: {messageText}");

        // --- Peek at messages (without making them invisible) ---
        PeekMessagesResult peekedMessages = await queueClient.PeekMessagesAsync(maxMessages: 1);
        if (peekedMessages.Messages.Count > 0)
        {
            Console.WriteLine($"Peeked message: {peekedMessages.Messages[0].MessageText}");
        }

        // --- Receive and process messages ---
        QueueMessage[] messages = (await queueClient.ReceiveMessagesAsync(maxMessages: 5, visibilityTimeout: TimeSpan.FromSeconds(30))).Value;

        foreach (QueueMessage message in messages)
        {
            Console.WriteLine($"Received message: {message.MessageText}");

            // Simulate processing the message
            await Task.Delay(1000); // Simulate work

            // Delete the message after successful processing
            await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
            Console.WriteLine($"Deleted message: {message.MessageId}");
        }
    }
}
            

Monitoring and Best Practices