February 12, 2017

Find the MQTT broker without an IP adress

If you, like me, like to built IoT devices based on ESP8266, you may use MQTT to send and receive messsages. One problem is to equip each device with the IP number of the MQTT broker. One solution is to add a simple management web server to the device and make it open a Wifi access point serving an admin page, when it is started the first time.

A better option is to use a service discovery protocol. The most popular protocol is known under the name mDNS, Avahi, Bonjour or Zeroconf. This protocol let you advertise the MQTT service on the local network and have your IoT devices find it without using an IP name or number.

Say that you run the MQTT broker Mosquitto at port 1883 on a Raspberry Pi.

Use nano to create a service description file:

sudo nano /etc/avahi/services/mosquitto.service

and paste the following text:

<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
 <name replace-wildcards="yes">Mosquitto MQTT server on %h</name>
  <service>
   <type>_mqtt._tcp</type>
   <port>1883</port>
   <txt-record>info=Publish, Publish! Read all about it! mqtt.org</txt-record>
  </service>

</service-group>

Save and exit with Ctrl-O <ENTER> Ctrl-X.

Now the Avahi daemon immediately advertises the mqtt service on your local network.
To see that it works, just open any service browser - I used Bonjour Browser from http://www.tildesoft.com/ on my Mac.

On the ESP8266 side, the following code example shows how to find the MQTT server ip and port.


#include <ESP8266mDNS.h>

...

if (!MDNS.begin("ESP")) { 
  Serial.println("Error setting up mDNS");
} else {
  Serial.println("mDNS setup finished");

  Serial.println("Sending mDNS Query");
  int n = MDNS.queryService("mqtt", "tcp");

  if (n == 0) {
    Serial.println("No service found");
  } else {
    // at least one MQTT service is found
    // ip no and port of the first one is MDNS.IP(0) and MDNS.port(0)
}