Flame_Phoenix
Flame_Phoenix

Reputation: 17564

How to listen to a queue using azure service-bus with Node.js?

Background

I have several clients sending messages to an azure service bus queue. To match it, I need several machines reading from that queue and consuming the messages as they arrive, using Node.js.

Research

I have read the azure service bus queues tutorial and I am aware I can use receiveQueueMessage to read a message from the queue.

However, the tutorial does not mention how one can listen to a queue and read messages as soon as they arrive.

I know I can simply poll the queue for messages, but this spams the servers with requests for no real benefit.

After searching in SO, I found a discussion where someone had a similar issue:

And I know they ended up using the C# async method ReceiveAsync, but it is not clear to me if:

  1. That method is available for Node.js
  2. If that method reads messages from the queue as soon as they arrive, like I need.

Problem

The documentation for Node.js is close to non-existant, with that one tutorial being the only major document I found.

Question

  1. How can my workers be notified of an incoming message in azure bus service queues ?

Upvotes: 2

Views: 3734

Answers (4)

Themasterhimself
Themasterhimself

Reputation: 1016

You can receive messages from the service bus queue via subscribe method which listens to a stream of values. Example from Azure documentation below

const { delay, ServiceBusClient, ServiceBusMessage } = require("@azure/service-bus");

// connection string to your Service Bus namespace
const connectionString = "<CONNECTION STRING TO SERVICE BUS NAMESPACE>"

// name of the queue
const queueName = "<QUEUE NAME>"

 async function main() {
    // create a Service Bus client using the connection string to the Service Bus namespace
    const sbClient = new ServiceBusClient(connectionString);

    // createReceiver() can also be used to create a receiver for a subscription.
    const receiver = sbClient.createReceiver(queueName);

    // function to handle messages
    const myMessageHandler = async (messageReceived) => {
        console.log(`Received message: ${messageReceived.body}`);
    };

    // function to handle any errors
    const myErrorHandler = async (error) => {
        console.log(error);
    };

    // subscribe and specify the message and error handlers
    receiver.subscribe({
        processMessage: myMessageHandler,
        processError: myErrorHandler
    });

    // Waiting long enough before closing the sender to send messages
    await delay(20000);

    await receiver.close(); 
    await sbClient.close();
}    
// call the main function
main().catch((err) => {
    console.log("Error occurred: ", err);
    process.exit(1);
 });

source : https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-nodejs-how-to-use-queues

Upvotes: 1

Navin Mistry
Navin Mistry

Reputation: 1

You can make use of serverless functions which are "ServiceBusQueueTrigger", they are invoked as soon as message arrives in queue,

Its pretty straight forward doing in nodejs, you need bindings defined in function.json which have type as

"type": "serviceBusTrigger",

This article (https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#trigger---javascript-example) probably would help in more detail.

Upvotes: 0

Delcon
Delcon

Reputation: 2545

I asked myslef the same question, here is what I found.

Use Google PubSub, it does exactly what you are looking for.

If you want to stay with Azure, the following ist possible:

  • cloud functions can be triggered from SBS messages
  • trigger an event-hub event with that cloud function
  • receive the event and fetch the message from SBS

Upvotes: 0

Flame_Phoenix
Flame_Phoenix

Reputation: 17564

Answer

According to Azure support, it is not possible to be notified when a queue receives a message. This is valid for every language.

Work arounds

There are 2 main work arounds for this issue:

  1. Use Azure topics and subscriptions. This way you can have all clients subscribed to an event new-message and have them check the queue once they receive the notification. This has several problems though: first you have to pay yet another Azure service and second you can have multiple clients trying to read the same message.

  2. Continuous Polling. Have the clients check the queue every X seconds. This solution is horrible, as you end up paying the network traffic you generate and you spam the service with useless requests. To help minimize this there is a concept called long polling which is so poorly documented it might as well not exist. I did find this NPM module though: https://www.npmjs.com/package/azure-awesome-queue

Alternatives

Honestly, at this point, you may be wondering why you should be using this service. I agree...

As an alternative there is RabbitMQ which is free, has a community, good documentation and a ton more features.

The downside here is that maintaining a RabbitMQ fault tolerant cluster is not exactly trivial.

Another alternative is Apache Kafka which is also very reliable.

Upvotes: 2

Related Questions