1
votes

I'm trying to read a message off the queue (notified rather than polling) using C# azure function.

I'm currently pushing a message onto the queue using a console app for now, see below.

There seems to be two different products, azure service bus and a queue within a storage account. The following code uses the later, I'm not sure how to read the message of the queue?

Many thanks,

Code example

StorageCredentials creds = new StorageCredentials(accountname, accountkey);
        CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
        CloudQueueClient queueClient = account.CreateCloudQueueClient();
        CloudQueue queue = queueClient.GetQueueReference("test-queue");
        queue.CreateIfNotExists();
        while (true)
        {
            CloudQueueMessage message = new CloudQueueMessage(JsonConvert.SerializeObject("my message"));
            queue.AddMessage(message);
        }

Update

After the comments and following links as suggested by experts trying to help I have tried the following code sample to push a message onto Azure Service Bus (i.e not a queue in a storage account)

namespace ConsoleApp1
{
    using System;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        const string ServiceBusConnectionString = "Endpoint=sb://xxx.servicebus.windows.net/;SharedAccessKeyName=xxx;SharedAccessKey=xxx";
        const string QueueName = "name_of_queue";
        static IQueueClient queueClient;

        public static async Task Main(string[] args)
        {
            const int numberOfMessages = 10;
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            await SendMessagesAsync(numberOfMessages);

            await queueClient.CloseAsync();
        }

        static async Task SendMessagesAsync(int numberOfMessagesToSend)
        {
            for (var i = 0; i < numberOfMessagesToSend; i++)
            {
                string messageBody = $"Message {i}";
                var message = new Message(Encoding.UTF8.GetBytes(messageBody));

                Console.WriteLine($"Sending message: {messageBody}");

                // Send the message to the queue
                try
                {
                    await queueClient.SendAsync(message);  // this line
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
    }
}

When I run the code above the console window doesn't do anything, no error message just nothing..! strange.. Looking in the azure service bus overview it active message count is zero.

I'm using this sample project but the queueClient.SendAsync never returns back. Do I need to set something up in azure, permissions perhaps?

https://github.com/Azure/azure-service-bus

Error eventually received

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

I can see requests within the portal service bus screen

1
"How to read message off azure service bus" -- this is very well documented. Can you show us what you have tried?Casey Crookston

1 Answers

3
votes

Is these what you want?

1.If you want to get message from azure service bus queue:

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace ConsoleApp2
{
    class Program
    {
        const string ServiceBusConnectionString = "xxxxxx";
        const string QueueName = "xxx";
        static IQueueClient queueClient;
        public static async Task Main(string[] args)
        {
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            RegisterOnMessageHandlerAndReceiveMessages();

            Console.ReadKey();

            await queueClient.CloseAsync();
        }
        static void RegisterOnMessageHandlerAndReceiveMessages()
        {
            var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
            {
                MaxConcurrentCalls = 10,
                AutoComplete = false
            };
            queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
        }
        static async Task ProcessMessagesAsync(Message message, CancellationToken token)
        {
            Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
            await queueClient.CompleteAsync(message.SystemProperties.LockToken);
        }
        static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
        {
            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
            var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
            Console.WriteLine("Exception context for troubleshooting:");
            Console.WriteLine($"- Endpoint: {context.Endpoint}");
            Console.WriteLine($"- Entity Path: {context.EntityPath}");
            Console.WriteLine($"- Executing Action: {context.Action}");
            return Task.CompletedTask;
        }
    }
}

Before receive from the service bus queue, I have put message in the queue. This is the result:

enter image description here

2.If you want to get message from azure storage queue:

using System;
using Microsoft.Azure; 
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Queue;

namespace ReceiveMessageFromAzureStorageQueue
{
    class Program
    {
        static void Main(string[] args)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse("xxxxxx");
            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
            CloudQueue queue = queueClient.GetQueueReference("xxx");
            CloudQueueMessage peekedMessage = queue.PeekMessage();
            queue.FetchAttributes();
            int? cachedMessageCount = queue.ApproximateMessageCount;
            Console.WriteLine("Number of messages in queue: " + cachedMessageCount);
            for(int i=0; i<cachedMessageCount; i++) {
                    System.Threading.Thread.Sleep(10);
                    CloudQueueMessage retrievedMessage = queue.GetMessage(TimeSpan.FromMilliseconds(10));
                    Console.WriteLine(retrievedMessage.AsString);
                    queue.DeleteMessage(retrievedMessage);
            }
            Console.WriteLine("Already Read.");
        }
    }
}

Still put messages in the azure storage queue before receive them. This is the result:

enter image description here

Please let me know if you have more doubts.