MQTT and Azure Functions


22 Sep 2018 / Kees Schollaart /

I’ve build an Azure Functions extension which enables you to subscribe an publish to MQTT topics.

Why

For multiple reasons MQTT gained a lot of popularity in the last couple of years. If you are interested in what MQTT is, I think this blogpost explains it very well. MQTT is used in the IoT domain a lot, I felt in love with it, when I started to use it as part of my Home Automation. So I’m fan because of the ease of use, the lightweight footprint and the broad support of technology-stacks.

I thought that MQTT would fit very well with the serverless patterns. In my first use case, I wanted to run some serverless code in the cloud when a message got published on a MQTT topic. Next to that, I quickly wanted to be able to publish messages as well.

In my world (Microsoft Azure), if we talk about serverless, that usually means Azure Functions. So my challenge was: can I ‘connect’ MQTT with Azure Functions?

Azure Functions

Azure Functions has the notion of input and output bindings, you could see them as triggers and results. There are a lot of implementations available out of the box developed by Microsoft. There are (at this time) two major releases of the Azure Functions host and SDK, being referred to as v1 and v2. This is important because only in v2 it’s possible to develop your own bindings.

What did I build?

I build the MQTT trigger and output bindings for Azure Functions v2. It’s open source and free to use, the code is available in my GitHub project CaseOnline.Azure.WebJobs.Extensions.Mqtt. An overview of how it works:

When your Function App host starts, the host will detect this extension. The extension will discover the functions with MQTT triggers, for each trigger a subscription will be created to the MQTT broker. The extension will also maintain the open connection with the MQTT broker.

This extension heavily depends upon the great work of Christian Kratky’sMQTTNet’. This is a .NET Standard implementation of a MQTT.

How to use

In your Azure Functions project reference the CaseOnline.Azure.WebJobs.Extensions.Mqtt NuGet package.

Below a simple example, receicing messages for topic my/topic/in and publishing messages on topic testtopic/out.

public static class ExampleFunctions
{
    [FunctionName("SimpleFunction")]
    public static void SimpleFunction(
        [MqttTrigger("my/topic/in")] IMqttMessage message,
        [Mqtt] out IMqttMessage outMessage,
        ILogger logger)
    {
        var body = message.GetMessage();
        var bodyString = Encoding.UTF8.GetString(body);
        logger.LogInformation($"{DateTime.Now:g} Message for topic {message.Topic}: {bodyString}");
        outMessage = new MqttMessage("testtopic/out", new byte[] { }, MqttQualityOfServiceLevel.AtLeastOnce, true);
    }
}

Resiliency

If you use the Azure Functions Consumption plan, the host will be terminated after 10 minutes of inactivity. Then also the open connection will be disconnected. Therefor: don’t use the Consumption Plan when you use triggers.

Next to that, this extension uses the Managed Client of the MQTT Client. This means:

  • The managed client is started once and will maintain the connection automatically including reconnecting etc.
  • All MQTT application messages are added to an internal queue and processed once the server is available.
  • All subscriptions are managed across server connections. There is no need to subscribe manually after the connection with the server is lost.

More info

Check the GitHub repository for more info:

Download the NuGet package:

Share your love with the developers who did the hard work: ‘Star’ the MQTTNet Repository:

Checkout these pages in the Wiki: