MQTT server#

Overview#

This tutorial demonstrates how Mongoose Library can be used to implement a simple MQTT 3.1.1 server that is capable of:

  1. Handling CONNECT requests from clients. User / password are not verified
  2. Handling SUBSCRIBE requests
  3. Handling PUBLISH request

This implementation, therefore, implements only a subset of MQTT specification, but it is enough for preforming some basic tasks, and is easy to extend.

A full source code for this tutorial is at https://github.com/cesanta/mongoose/tree/master/tutorials/mqtt/mqtt-server

Global variables#

First we declare global variables to make it easy to change tunable parameters. In our case it is one - a listening address:

Also, we need to keep a list of subscriptions. For each SUBSCRIBE request, we'd like to store which connection requested it, which QoS, and which topic:

Signal handler#

It is a best practice to register a signal handler. Our signal handler function just sets a global variable which will be checked in the event loop:

Main function#

The main() function is usual - we initialise an event manager, create a listening connection, and fall into an event loop until a termination signal is received. Then we cleanup and exit:

Event handler#

The event handler function is the meat of the server implementation. It handles two events: MG_EV_CLOSE and MG_EV_MQTT_CMD. The code that handles MG_EV_MQTT_CMD looks up which specific command has been sent:

Handling MQTT CONNECT#

We perform some sanity check for the received data, check that the client is using MQTT version 3, and send a successful CONNACK response back.

A CONNECT command sent by a client may contain extra settings - like user, password, will message, "clean session" flag, client ID, and others. We silently ignore them.

Handling MQTT SUBSCRIBE#

When SUBSCRIBE command is received, it may contain multiple topic names with QoS for each. We iterate over all topics using mg_mqtt_next_sub API function, and for each requested topic, create a subscription descriptor and add it to the global list of subscription, s_subs. Next we send a SUBACK acknowledgement with a number of topics we've handled.

Handling MQTT PUBLISH#

Hadling PUBLISH requests is easy - we iterate a list of subscriptions, compare topic names, and send the message to the subscribed connection if topics match. We use mg_globmatch() as a matching function, which handles wildcards.

Handling disconnection#

When a client disconnects, we iterate over the global subscription list, and remove all subscriptions installed by that client.

Testing#

Let's test our server. Follow the Build Tools tutorial to setup your development environment. Start a terminal in the project directory; clone the Mongoose Library repo, and execute:

make clean all

Make sure you have mosquitto client setup on your workstartion. Start another terminal and subscribe to three topics: a/#, b/+/test and c/foo

~$ mosquitto_sub -v -h localhost -p 1883 -t 'a/#' -t 'b/+/test' -t c/foo

Start another terminal. Let's publish messages! First, send a message to a topic d/. We are not subscribed to that topic so should not see anything in the "subscribed" terminal:

$ mosquitto_pub -h localhost -p 1883 -t d/ -m hello

Now let's send to a topic c/foo, which we should catch:

$ mosquitto_pub -h localhost -p 1883 -t c/foo -m hello

Also, we should catch a message on topic b/123/test:

$ mosquitto_pub -h localhost -p 1883 -t b/123/test -m hello

And of course on topic a/what/ever:

$ mosquitto_pub -h localhost -p 1883 -t a/what/ever -m hello

We use cookies to enhance your experience - see our privacy policy. By continuing to visit this site you agree to our use of cookies. Yes, I Agree