MQTT connectivity issues with API

0 votes

Suppose I have an IoT device which I'm about to control (lets say switch on/off) and monitor (e.g. collect temperature readings). It seems MQTT could be the right fit. I could publish messages to the device to control it and the device could publish messages to a broker to report temperature readings. So far so good.

The problems start to occur when I try to design the API to control the device.

Lets day the device subscribes to two topics:

  • /device-id/control/on
  • /device-id/control/off

Then I publish messages to these topics in some order. But given the fact that messaging is typically an asynchronous process there are no guarantees on the order of messages received by the device.

So in case two messages are published in the following order:

  1. /device-id/control/on
  2. /device-id/control/off

they could be received in the reversed order leaving the device turned on, which can have dramatic consequences, depending on the context.

Of course the API could be designed in some other way, for example there could be just one topic

  1. /device-id/control

and the payload of individual messages would carry the meaning of an individual message (on/off). So in case messages are published to this topic in a given order they are expected to be received in the exact same order on the device.

But what if the order of publishes to individual topics cannot be guaranteed? Suppose the following architecture of a system for IoT devices:

                       / control service \
application -> broker -> control service -> broker -> IoT device
                       \ control service /

The components of the system are:

  • an application which effectively controls the device by publishing messages to a broker
  • a typical message broker
  • a control service with some business logic

The important part is that as in most modern distributed systems the control service is a distributed, multi instance entity capable of processing multiple control messages from the application at a time. Therefore the order of messages published by the application can end up totally mixed when delivered to the IoT device.

Now given the fact that most MQTT brokers only implement QoS0 and QoS1 but no QoS2 it gets even more interesting as such control messages could potentially be delivered multiple times.

My point is that separate topics for control messages is a bad idea. The same goes for a single topic. In both cases there are no message delivery order guarantees.

The only solution to this particular issue that comes to my mind is message versioning so that old (out-dated) messages could simply be skipped when delivered after another message with more recent version property.

  • Am I missing something?
  • Is message versioning the only solution to this problem?
Sep 24, 2018 in IoT (Internet of Things) by Matt
• 2,270 points

1 answer to this question.

0 votes

Am I missing something?

Most definitely. The example you brought up is a generic control system, being attached to some message-oriented scheme. There are a number of patterns that can be used when referring to a message-based architecture. This article by Microsoft categorizes message patterns into two primary classes:

  • Commands and
  • Events

The most generic pattern of command behavior is to issue a command, then measure the state of the system to verify the command was carried out. If you forget to verify, your system has an open loop. Such open loops are (unfortunately) common in IT systems (because it's easy to forget), and often result in bugs and other bad behaviors such as the one described above. So, the proper way to handle a command is:

  1. Issue the command
  2. Inquire as to the state of the system
  3. Evaluate next action

Events, on the other hand, are simply fired off. As the publisher of an event, it is not my business to worry about who receives the event, in what order, etc. Now, it should also be pointed out that the use of any decent message broker (e.g. RabbitMQ) generally carries strong guarantees that messages will be delivered in the order which they were originally published. Note that this does not mean they will be processed in order.

So, if you treat a command as an event, your system is guaranteed to act up sooner or later.

Is message versioning the only solution to this problem?

Message versioning typically refers to a property of the message class itself, rather than a particular instance of the class. It is often used when multiple versions of a message-based API exist and must be backwards-compatible with one another.

What you are instead referring to is unique message identifiers. Guids are particularly handy for making sure that each message gets its own unique id. However, I would argue that de-duplication in message-based architectures is an anti-pattern. One of the consequences of using messaging is that duplicates are possible, so you should try to design your system behaviors to be stateless and idempotent. If this is not possible, it should be considered that messaging may not be the correct communication solution for the need.

Using the command-event dichotomy as an example, you could perform the following transaction:

  1. The controller issues the command, assigning a unique identifier to the command.
  2. The control system receives the command and turns on.
  3. The control system publishes the "light on" event notification, containing the unique id of the command that was used to turn on the light.
  4. The controller receives the notification and correlates it to the original command.

In the event that the controller doesn't receive notification after some timeout, the controller can retry the command. Note that "light on" is an idempotent command, in that multiple calls to it will have the same effect.

answered Sep 24, 2018 by anonymous2
• 4,280 points

Related Questions In IoT (Internet of Things)

0 votes
1 answer

MQTT pubish is slow to send with ESP8266 & NodeMCU

I think you're almost correct and on ...READ MORE

answered Aug 1, 2018 in IoT (Internet of Things) by nirvana
• 3,130 points
0 votes
1 answer

Pair and connect new devices using Bluez5 DBUS API with C++

Although high-level APIs like Qt5, which also ...READ MORE

answered Oct 8, 2018 in IoT (Internet of Things) by nirvana
• 3,130 points
+1 vote
1 answer

Configuring Raspberry Pi with Windows 10 IoT App using Rest API

You should use HttpClient instead of WebClient. Try ...READ MORE

answered Oct 10, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
0 votes
1 answer
0 votes
1 answer

MQTT protocol connection error

Ok so you need two libraries to ...READ MORE

answered Jul 6, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points

reshown Jul 6, 2018 by Vardhan 2,880 views
0 votes
1 answer

Mosquitto 1.4.2 Websocket support

down vote In the dir mosquitto-1.4.X edit the ...READ MORE

answered Jul 9, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
0 votes
1 answer

IoT request response protocol

Based on your requirement of a light ...READ MORE

answered Jul 13, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
0 votes
1 answer

What is the maximum message length for a MQTT broker?

It's not entirely clear what you're asking ...READ MORE

answered Jul 17, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
0 votes
1 answer

Issues with Intel Edison MRAA module

You can work on this choice:- In the ...READ MORE

answered Jul 11, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
0 votes
1 answer

MQTT on ESP8266 with NodeMCU - problems with publishing

Perhaps this was solved by more recent ...READ MORE

answered Aug 13, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP