Tutorial: Receiving Events from Azure Event Hubs

This tutorial will guide you through the process of receiving events from an Azure Event Hub using a simple client application. We'll cover setting up your environment, writing the code, and running it to consume messages.

Prerequisites

Step 1: Set Up Your Project

Create a new directory for your project and initialize a Node.js project:

Terminal
mkdir event-hub-receiver
cd event-hub-receiver
npm init -y

Next, install the necessary Azure Event Hubs client library for Node.js:

Terminal
npm install @azure/event-hubs

Step 2: Write the Receiver Code

Create a new file named receiver.js and add the following code. Replace YOUR_EVENTHUB_CONNECTION_STRING and YOUR_EVENTHUB_NAME with your actual values.

receiver.js

const { EventHubClient, EventPosition } = require("@azure/event-hubs");

// Replace with your Event Hubs connection string and hub name
const connectionString = "YOUR_EVENTHUB_CONNECTION_STRING";
const eventHubName = "YOUR_EVENTHUB_NAME";

async function main() {
    console.log("Starting Event Hubs receiver...");

    const client = new EventHubClient(connectionString);

    // Get information about the Event Hub partitions
    const partitionIds = await client.getPartitionIds(eventHubName);
    console.log("Event Hubs partitions:", partitionIds);

    // Create a consumer for each partition
    for (const partitionId of partitionIds) {
        console.log(`Starting to listen to partition: ${partitionId}`);

        // Create a consumer client for this partition
        const consumer = client.createConsumer(
            EventPosition.latest(), // Start from the latest event
            { partitionId: partitionId }
        );

        // Set up an event handler for received messages
        consumer.subscribe(
            {
                processEvents: async (events, context) => {
                    if (events.length === 0) {
                        console.log(`No new events received for partition ${partitionId}`);
                        return;
                    }

                    console.log(`\n--- Events from Partition ${partitionId} ---`);
                    for (const event of events) {
                        console.log(`  Sequence Number: ${event.sequenceNumber}`);
                        console.log(`  Offset: ${event.offset}`);
                        console.log(`  Enqueued Time: ${event.enqueuedTime}`);
                        console.log(`  Body: ${event.body}`);
                        // You can access event.body as a Buffer or string
                        // console.log("  Body (string):", event.body.toString());
                    }
                    console.log(`-------------------------------------\n`);

                    // Update the checkpoint if you are using checkpointing
                    // await context.updateCheckpoint(event);
                },
                processError: async (err, context) => {
                    console.error(`Error in partition ${context.partitionId}: ${err.message}`);
                }
            }
        );
    }

    console.log("Receiver is running. Press Ctrl+C to stop.");

    // Keep the process alive to listen for events
    process.on("SIGINT", async () => {
        console.log("Stopping Event Hubs receiver...");
        await client.close();
        process.exit(0);
    });
}

main().catch((err) => {
    console.error("An error occurred:", err);
    process.exit(1);
});

Tip: For production scenarios, consider using a more robust error handling strategy and checkpointing to track processed events, preventing message loss or duplication. You can also start from a specific sequence number or enqueued time instead of EventPosition.latest().

Step 3: Run the Receiver

Make sure you have replaced the placeholder connection string and Event Hub name in receiver.js. Then, run the script from your terminal:

Terminal
node receiver.js

You should see output indicating that the receiver has started and is listening to each partition. When events are sent to your Event Hub, they will be logged to your console.

Step 4: Sending Events (Optional)

To test the receiver, you can send events to your Event Hub using another script or the Azure Portal. Here's a basic example of how to send events using the same Azure Event Hubs SDK:

Create a file named sender.js:

sender.js

const { EventHubProducerClient } = require("@azure/event-hubs");

const connectionString = "YOUR_EVENTHUB_CONNECTION_STRING";
const eventHubName = "YOUR_EVENTHUB_NAME";

async function main() {
    const producerClient = new EventHubProducerClient(connectionString, eventHubName);
    const batch = await producerClient.createBatch();

    batch.tryAdd({ body: "Hello Event Hubs!" });
    batch.tryAdd({ body: { message: "Another message", timestamp: new Date() } });
    batch.tryAdd({ body: JSON.stringify({ complex: "data", value: 123 }) });

    console.log("Sending events...");
    await producerClient.sendBatch(batch);
    console.log("Events sent successfully!");

    await producerClient.close();
}

main().catch((err) => {
    console.error("An error occurred:", err);
});

Run the sender script:

Terminal
node sender.js

After running the sender, switch back to your running receiver.js terminal, and you should see the sent events being received and logged.

Conclusion

You have successfully set up an Azure Event Hubs receiver and processed incoming events. This tutorial provides a foundational understanding; explore the Azure SDK for Node.js documentation for advanced features like batching, checkpointing, and managing consumer groups.