Skip to content
On this page

Using MQTT

WARNING

Wolverine requires the V5 version of MQTT for its broker support

The Wolverine 1.9 release added a new transport option for the MQTT standard common in IoT Messaging.

Installing

To use MQTT as a transport with Wolverine, first install the Wolverine.MQTT library via nuget to your project. Behind the scenes, this package uses the MQTTnet managed library for accessing MQTT brokers and also for its own testing.

bash
dotnet add WolverineFx.Mqtt

In its most simplistic usage you enable the MQTT transport through calling the WolverineOptions.UseMqtt() extension method and defining which MQTT topics you want to publish or subscribe to with the normal subscriber rules as shown in this sample:

cs
using var host = await Host.CreateDefaultBuilder()
    .UseWolverine((context, opts) =>
    {
        // Connect to the MQTT broker
        opts.UseMqtt(builder =>
        {
            var mqttServer = context.Configuration["mqtt_server"];

            builder
                .WithMaxPendingMessages(3)
                .WithClientOptions(client =>
                {
                    client.WithTcpServer(mqttServer);
                });
        });

        // Listen to an MQTT topic, and this could also be a wildcard
        // pattern
        opts.ListenToMqttTopic("app/incoming")
            
            // The default is AtLeastOnce
            .QualityOfService(MqttQualityOfServiceLevel.AtMostOnce);

        // Publish messages to an outbound topic
        opts.PublishAllMessages()
            .ToMqttTopic("app/outgoing");
    })
    .StartAsync();

snippet source | anchor

INFO

The MQTT transport at this time only supports endpoints that are either Buffered or Durable.

WARNING

The MQTT transport does not really support the "Requeue" error handling policy in Wolverine. "Requeue" in this case becomes effectively an inline "Retry"

Broadcast to User Defined Topics

As long as the MQTT transport is enabled in your application, you can explicitly publish messages to any named topic through this usage:

cs
public static async Task broadcast(IMessageBus bus)
{
    var paymentMade = new PaymentMade(200, "EUR");
    await bus.BroadcastToTopicAsync("region/europe/incoming", paymentMade);
}

snippet source | anchor

Publishing to Derived Topic Names

INFO

The Wolverine is open to extending the options for determining the topic name from the message type, but is waiting for feedback from the community before trying to build anything else around this.

As a way of routing messages to MQTT topics, you also have this option:

cs
using var host = await Host.CreateDefaultBuilder()
    .UseWolverine((context, opts) =>
    {
        // Connect to the MQTT broker
        opts.UseMqtt(builder =>
        {
            var mqttServer = context.Configuration["mqtt_server"];

            builder
                .WithMaxPendingMessages(3)
                .WithClientOptions(client =>
                {
                    client.WithTcpServer(mqttServer);
                });
        });

        // Publish messages to MQTT topics based on
        // the message type
        opts.PublishAllMessages()
            .ToMqttTopics()
            .QualityOfService(MqttQualityOfServiceLevel.AtMostOnce);
    })
    .StartAsync();

snippet source | anchor

In this approach, all messages will be routed to MQTT topics. The topic name for each message type would be derived from either Wolverine's message type name rules or by using the [Topic("topic name")] attribute as shown below:

cs
[Topic("one")]
public class TopicMessage1
{
}

snippet source | anchor

cs
[Topic("color.blue")]
public class FirstMessage
{
    public Guid Id { get; set; } = Guid.NewGuid();
}

snippet source | anchor

Released under the MIT License.