Skip to content

Tips and Tricks

HansM edited this page Sep 19, 2021 · 15 revisions

Logging

It is recommended to disable logging (Global logger or custom logger) which running in a live environment because it adds a huge overhead to message processing. It should be avoided to attach to the global MQTTnet logger at all because an already attached method (which may not process the entry further on) leads to generation of log messages internally.

Prefer builders

MQTTnet comes with some builders like the MqttClientOptionsBuilder or MqttApplicationMessageBuilder which are supporting a fluent API. Also these builders are used to achieve version compatibility. It is supported to change the MqttClientOptions class directly but this file may have breaking changes across versions of MQTTnet. The builders instead will usually provide backward compatibility (when possible).

MQTT best practices

This project only covers the implementation of a basic MQTT library. For best practices, general recommendation and specifications please visit https://www.hivemq.com/mqtt/. A small section on MQTT topics is avaiable in the wiki under https://github.com/chkr1011/MQTTnet/wiki/MQTT-topics, too.

Prevent processing event published by server

The server (broker) does not distinguish between clients and itself. Every message is treated the same way. But it is supported to skip events from the server itself by checking the ClientId property. If this is set to null the message was sent by the server directly and processing can be skipped.

Windows IoT Core and UWP localhost loopback addresses

In Windows IoT Core as well as in UWP, loopback connections (127.0.0.1) are not allowed. If you try to connect to a locally running server (broker), this will fail.

Special notice for using the server project in Android

Under Android, there is an issue with the default bound IP address. So you have to use the actual address of the device. Check the example below.

IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];

var server = new MqttFactory().CreateMqttServer();
server.StartAsync(new MqttServerOptionsBuilder()
    .WithDefaultEndpointBoundIPAddress(ipAddress)
    .WithDefaultEndpointBoundIPV6Address(IPAddress.None)
    .Build()).GetAwaiter().GetResult();

Accessing the MQTT server in an ASP.NET MVC controller

If we have an ASP.NET Core application that needs to send MQTT messages from an MVC controller, the MqttService singleton needs to be registered with dependency injection. The trick is to have two methods to correctly setup the MQTT part:

  1. Have MqttService implement all the interfaces needed to hook with MqttServer (like IMqttServerClientConnectedHandler, IMqttServerApplicationMessageInterceptor, etc.)

  2. Write a ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options) method that sets up the current object as callback for the needed methods:

public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
{
    options.WithConnectionValidator(this);
     options.WithApplicationMessageInterceptor(this);
}
  1. Write a ConfigureMqttServer(IMqttServer mqtt) that stores the reference to the MQTT server for later use and setup the handlers:
public void ConfigureMqttServer(IMqttServer mqtt)
{
    this.mqtt = mqtt;
    mqtt.ClientConnectedHandler = this;
    mqtt.ClientDisconnectedHandler = this;
}

Then, in your Startup class configure and use the service.

In ConfigureServices:

services.AddSingleton<MqttService>();
services.AddHostedMqttServerWithServices(options => {
    var s = options.ServiceProvider.GetRequiredService<MqttService>();
    s.ConfigureMqttServerOptions(options);
});
services.AddMqttConnectionHandler();
services.AddMqttWebSocketServerAdapter();

In Configure:

app.UseMqttEndpoint();
app.UseMqttServer(server => app.ApplicationServices.GetRequiredService<MqttService().ConfigureMqttServer(server));

Performance testing

If you are looking at performance, make sure to run in release mode and without debugger attached. Otherwise Visual Studio will slow things down painfully. Also you may want to disable console logging if you use it that can also slow things down extremely.

Limits for multi-subscriptions per single call

In AWS IoT Core, there is a limit of 8 topic filters per subscription.