Sending and receiving MQTT messages in Android and iOS Applications
Internet of Things (IoT) devices, which are using connection to the Internet in order to send and receive sensor data and powered by affordable micro controllers like Arduino and Raspberry PI, can be seen more and more in our everyday lives. Smart IoT devices can range from microwaves, washing machines to vehicles.
MQTT (Message Queuing Telemetry Transport) is lightweight, publish-subscribe network protocol that transports messages between devices.
It was invented by Andy Stanford-Clark (IBM) and Arlen Nipper (Cirrus Link, then Eurotech) in 1999, and it was used to monitor an oil pipeline through the desert. The main goal was to have a protocol that is bandwith-efficient, lightweight and uses little power, because the devices were connected by satellite link and this was very expensive at a time.
In MQTT protocol, an MQTT Broker is a server that receives messages from the clients (also called publishers) and publishes these messages to appropriate clients (also called subscribers). Each client that publishes some message, it publishes it within some topic and each client that want to receive messages from certain topic, must subscribe to that topic.
Topic is simple string like ‘temperature’ and it can contain multiple hierarchy levels, separated by slash character. It’s also possible to subscribe to multiple hierarchy levels, using wildcard characters (like multilevel wildcard character ‘#’). For example, ‘room/#’ is subscribing to all topics beginning with ‘room’.
The main difference between MQTT and HTTP is that in MQTT, client doesn’t need to pull the information, because the broker automatically pushes the new information to the clients, via TCP protocol. If the connection is interrupted by some unknown circumstance, MQTT broker can put unsent messages into buffer and resend them to the client, as soon as client becomes online again.
After this brief introduction in MQTT, let us see what we are going to build in this article. We are going to use public HiveMQ MQTT broker:
and we are going to build an Android and iOS application that will send and receive messages between themselves. During development, we’ll also use HiveMQ WebSocket client:
for as publisher. Message that we are going to send via MQTT is simple text message.
In the bottom of the article, you’ll find GitHub links with code samples from this article so if you missed some step from this article, you can still use the code from code samples.
Creating Android MQTT Client
In our newly created android project, we’ll insert libraries that will enable us to communicate with MQTT broker:
and in order for MQTT to work nicely, we’ll need to add one more additional dependency:
In android manifest, we need to add appropriate permissions:
and we need to add MQTT service, in ‘application’ section of manifest:
Basic dependency configuration is done, so we are now going to design layout of our application and make an class that will be responsible for sending and receiving MQTT messages.
We are going to create layout of ‘Main’ activity, as following:
After the layout is done, we are going to create class that will be responsible for MQTT communication. So for that purpose, we are going to create interface ‘MqttManager’ that will specify which methods our class will contain:
Let us start implementing ‘MqttManagerImpl’. The very first thing that is important to specify is that our class should implement ‘MqttManager’ interface:
In class constructor we can see different attributes like ‘serverUri’ that will be used in methods inside our class. In our MQTT manager class we are going to use two variables:
the first one ‘mqttAndroidClient’ is object that will do all the hard work of sending and receiving MQTT messages.
Variable ‘mqttStatusListener’ is listener that will notify us after some message or some other event like exception has occurred:
As we can see that we need to implement three methods from ‘MqttManager’ interface, we’ll start by implementing the first one:
In ‘init’ method we are initializing android MQTT client and assigning connection callback listener. After the connection is successfully established, we need to subscribe to topic, in order to receive messages sent to this topic. Here we can see some other callback methods like ‘connectionLost’ that is notified when MQTT connection is broken or ‘messageArrived’ which will be invoked when new message is received.
The second method that we’ll need to implement is method for establishing the MQTT connection:
After we have successfully connected, we’ll start method for subscribing to the topics. In method for establishing connection, we need to specify connection options and for that, we are going to use ‘createConnectOptions’ method.
Option ‘isAutomaticReconnect’ set to ‘true’ means that in case if MQTT client was disconnected because of any unknown reason, MQTT library will retry to connect by itself automatically. Option ‘isCleanSession’ set to ‘false’ means that both client and server will maintain the state across restarts of the client, server and the connection.
After connection is established, we are going to specify buffer options, that will be responsible of holding the unsent messages in buffer and send them automatically, after the connection is reestablished:
Method for subscribing to the topic requires to have list of topics and a list of QoS (Quality of Service) for each topic:
There are 3 QoS levels in MQTT:
At most once (0)
- There is no guarantee of delivery, and that’s also the reason why this QoS level is also called ‘fire and forget’
At least once (1)
- Guarantees that the message is delivered at least once to the receiver. It is possible that message is sent or delivered multiple times.
Exactly once (2)
- Guarantees that the message is received only once by the intended recipients.
The last message that we need to implement in our ‘MqttManagerImpl’ class is responsible for sending messages to specified topic:
As you can see, we need to convert string into byte array before publishing the message to the MQTT broker.
Very nice, we have created our ‘MQTTManagerImpl’ class and we can proceed with integration of this class in our main activity.
First of all, we are going to start with specifying some constants above main activity class declaration:
In ‘onCreate’ method of main activity we are going to create new instance of ‘MqttManagerImpl’, using the configuration options from the constants above. After making an instance or ‘MqttManagerImpl’, we are going initialize it (by invoking ‘init’ method), register status listener and then we are going to invoke connect method.
MQTT status listener will display different MQTT statuses and messages in debug log or in layout TextView view:
Method ‘displayInDebugLog’ displays the MQTT status message in android debug log and method ‘displayInMessagesList’ displays received MQTT message in main activity layout.
The last method that we need to implement is ‘submitMessage’ which is responsible to check if user message is specified and to send it to MQTT broker via ‘MQTTManagerImpl’:
The next step is to send test message from HiveMQ public client to our android application.
In order to do that, we need to do the following steps:
- Open the following web application:
- Click to ‘Connect’ button with default connection data.
- In ‘Subscriptions’ tab, add subscription to the following topic: ‘messagesFromCroatia/#’, so in web application we’ll be able to receive messages sent from android or IOS apps.
- In Publish tab:
- add ‘messagesFromCroatia’ as topic
- add some message in ‘Message’ field, and click on ‘Publish’ in order to send message to our android application
If you have added configuration from above, you’ll see messages that are sent from web application in android application and vice versa.
Congratulations, you have successfully created android MQTT client.
The next step is to create IOS MQTT client.
Creating MQTT iOS Client
Very first thing is to add the following pod:
and after installing this pod, reopen XCode via newly created workspace.
Then, we need to create very simple interface (in ‘Main.storyboard’), with layout like it’s displayed in the following image:
And we need to create two outlets:
First one, ‘messageInputField’ is outlet to UITextField where user will be able to add some message. Outlet ‘messagesLabel’ is connected to UILabel in ScrollView and it will display received MQTT messages.
The next step is to create IBAction, and connect it with our ‘Submit’ button:
So far, we have connected our views to appropriate outlets and actions. Now it’s important to start MQTT client and initialize connection.
Object ‘session’ is main MQTT client object, responsible for sending and receiving MQTT messages. Methods ‘createMqttSocketTransport’ and ‘connectToMqtt’ will be specified in extension methods below, and they will be responsible for establishing MQTT connection with broker.
The next step is to create extension for our main ViewController, where we are going to put methods for establishing MQTT connection and it will implement MQTTSessionDelegate:
In method ‘createMqttSocketTransport’, we are specifying some configuration data for connection to MQTT broker.
Method ‘handleEvent’ is used for handling MQTTSession events. When event ‘connected’ has occurred we are able to subscribe to topics, by invoking ‘subscribeToTopic’ method. Method ‘TRACE’ is simple method used only for debug logging.
Another methods that we need implement by MQTTSessionDelegate are:
Where method callback ‘newMessage’ is method which is invoked when some message is received, and in this case we are displaying received message in UILabel by invoking ‘displayMessageLog’ method.
Now we are going to create methods for starting MQTT connection, subscribing to topics and sending message to MQTT broker:
So far, we have implemented methods for establishing MQTT connection, receiving and sending messages. Remaining methods to implement are methods for displaying logs and some methods for clearing input or displaying message alert dialog, which we can create in separate ViewController extension:
By now, we have created all required steps in order for our app to work. We can start the app now and try to send messages from our android app or from HiveMQ web client application to our iOS application and vice versa.
If you didn’t receive any messages, you always can checkout samples from GitHub account, which are in the bottom of this article and check what you have missed to write.
Congratulations, you have succeeded to implement both Android and IOS MQTT client applications and you now have idea on how everything is working with MQTT protocol. I wish you a lot of IoT projects, implemented by MQTT protocol :)
GitHub repositories with sample applications:
PS: If you are interested in robust MQTT broker, I would recommend to you HiveMQ. If you are exploring MQTT and IoT, I would recommend CloudMqtt (www.cloudmqtt.com) because for only 5 USD/month you can use Mosquitto MQTT broker in the cloud and their web application interface is very nice and easy to use.