The answer is simple: MQTT is pretty much the only standard protocol nowadays that makes it easy to send commands to the connected devices.

There are two typical IoT use cases:

  1. A connected device sends data to the remote server. This is easy. Any cloud with suitable API (RESTful or other) can take the data. Firewalls allow outbound connections:

  1. A connected device needs to be controlled remotely. This is a problem because devices are typically behind firewalls. Firewalls disallow inbound connections, making it impossible to connect to the device from the outside:

This is the point where HTTP protocol does not provide any standard mean of exposing RESTful functionality to the outside world. And CoAP, another popular IoT protocol, does not. And WebSocket does not.

MQTT does. A device connects to the MQTT server (punching through the firewall) and can "subscribe" to the topics, and anybody with the right credentials can also connect to the same MQTT server and "publish" messages to these topics. MQTT server routes published messages to the subscribers.

Thus, MQTT is pretty much the only popular standard protocol that makes a device instantly visible through the MQTT's SUBSCRIBE mechanism. But since MQTT is publish/subscribe rather than request/response, it is easy to send a command, but not easy to get a response. MQTT protocol is not designed to do that. Thus people use workarounds to implement request/response patterns on top of MQTT.

Typically, a device subscribes to a "commands" topic and sends responses to the "replies" topic. Whoever sends a command shall also subscribe to the "replies" topic and filter out replies sent to other clients. To do it properly, one must introduce IDs / sequence numbers, retransmits, and so on - and suddenly MQTT is not that easy anymore.

In the next article, I will show you how to solve device connectivity issue and use old good HTTP/RESTful to control remote devices easily, without torturing MQTT to do the job.