DEV Community

pul
pul

Posted on

NodeJS + Azure Service Bus + Windows Service

In this tutorial we will see how to create a little nodejs service that react to Azure Service Bus Queue events.

This could be useful in situation when you have an hybrid environment cloud + on premise and you want to orchestrate some kind of job that has to be done on premise.

This is not the only use case but it’s simple and common enough to be useful as a tutorial.

We will see how to create a Service Bus resource on Azure, how to configure a queue and how to create a small nodejs windows service that can consume the queue.

Setup

I’ll assume you already have an Azure Subscription and a Resource Group.

If not you can use the Azure Free Tier.

Create a new resource in your Resource Group, in this case you have to search for Service Bus,

Service Bus resource creation on the Azure portal

Fill the required fields. I’ve choose the West Europe Location just because is closer to me and the Basic pricing tier.

If you plan to use topics instead of queues or both you have to choose at least the Standard pricing tier since the topic and subscription feature is not supported from the Basic plan.

In this case you can leave all the other options as default and continue with the resource creation.

Create a queue

Once you have your service bus up and running you can create your first queue.

It’s very easy you just have to navigate to the Overview page of the newly created Service Bus resource and click on “Create Queue”.

There are not many options to fill in, I've used the name “test-queue” and left all the defaults.

Resource setup

Consume queue events

Now we can develop a little nodejs script installed as a Windows service that listen for Service Bus queue event end log in the OS Event Log,

We will use the official nodejs library for interacting with the service bus and the node-windows package to create the Windows service.

Project setup

Create a new folder “service-bus-daemon” on your filesystem.

Initialize a node project with the command

npm init -y
Enter fullscreen mode Exit fullscreen mode

Install the dependencies

npm install @azure/service-bus node-windows@1.0.0-beta.6
Enter fullscreen mode Exit fullscreen mode

We will install the 1.0.0-beta.6 version of node-windows because at the time of writing the latest version 1.0.0-beta.7 has a bug that affect the service start.

Service development

Create 3 files in the root folder of your project.

  • index.js is the main file where you can add your business logic
  • .env contains all the environment variables
  • install.js will install the script as a service on your machine
  • uninstall.js will uninstall the previously created service
// file index.js
const { ServiceBusClient } = require("@azure/service-bus");
const EventLogger = require('node-windows').EventLogger;
require('dotenv').config();

const SERVICE_NAME = process.env.SERVICE_NAME;
const QUEUE_NAME = process.env.QUEUE_NAME;
const CONNECTION_STRING = process.env.CONNECTION_STRING;

// log directly in the Windows Event Log
log = new EventLogger(SERVICE_NAME);

const queueName = QUEUE_NAME
const sbClient = new ServiceBusClient(CONNECTION_STRING);
const receiver = sbClient.createReceiver(queueName);

async function main(receiver) {

    const myMessageHandler = async (messageReceived) => {
        log.info(`Received message: ${messageReceived.body}`);
    };

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

    receiver.subscribe({
        processMessage: myMessageHandler,
        processError: myErrorHandler
    });
} 

async function closeAll(receiver, sbClient) {
    await receiver.close(); 
        await sbClient.close();
    process.exit(0);
}

main(receiver).catch((err) => {
    log.error(err);
    process.exit(1);
 });

process.on('SIGTERM', () => {
    log.info('Process terminated SIGTERM');
    closeAll(receiver, sbClient);
});

process.on('SIGINT', () => {
    log.info('Process terminated SIGINT');
    closeAll(receiver, sbClient);
});

process.on('SIGKILL', () => {
    log.info('Process terminated SIGKILL');
    closeAll(receiver, sbClient);
});
Enter fullscreen mode Exit fullscreen mode
// file install.js
require('dotenv').config();

const SERVICE_NAME = process.env.SERVICE_NAME;

var Service = require('node-windows').Service;

// Create a new service object
var svc = new Service({
  name: SERVICE_NAME,
  description: 'React to service bus queue messages',
  script: require('path').join(__dirname,'index.js'),
});

// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
    // start the process
  svc.start();
});

svc.install();
Enter fullscreen mode Exit fullscreen mode
// file uninstall.js
require('dotenv').config();

const SERVICE_NAME = process.env.SERVICE_NAME;

var Service = require('node-windows').Service;

// Create a new service object
var svc = new Service({
    name: SERVICE_NAME,
    script: require('path').join(__dirname,'index.js')
});

// Listen for the "uninstall" event so we know when it's done.
svc.on('uninstall',function(){
  console.log('Uninstall complete.');
  console.log('The service exists: ',svc.exists);
});

// Uninstall the service.
svc.uninstall();
Enter fullscreen mode Exit fullscreen mode

Install and test the service

In order to install the service you have to run

node install.js
Enter fullscreen mode Exit fullscreen mode

node-windows will create an .exe wrapper of your script and it will create the service for you.

You can test it by creating a message in the queue directly from the Azure Portal using the storing explorer as follow:

Path to online service bus explorer 1

Path to online service bus explorer 2

Path to online service bus explorer 3

If you want to uninstall the service you just have to run

node uninstall.js
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial we've created a small script that can be useful as a starting point for creating a windows service with node js and Azure Service Bus.

Top comments (0)