Handling MQTT Subscriptions with Swift on Linux

| | 0 Comments| 6:54 AM
Categories:

In our last post we looked at a Swift MQTT client which published information to a HiveMQ broker. Now let’s turn our attention to writing an MQTT client that subscribes to a topic.

Again, we’ll be using MQTT, code that aims to provide a solid MQTT client library implementation in Swift. If you haven’t yet read the tutorial on building an MQTT publisher with it, I suggest you do so before proceeding!

There are two basic components to writing an MQTT client that subscribes to a topic:

  • subscribing to a topic
  • handling a published message from the broker

Ignoring the boilerplate connection logic for a moment, let’s look at subscribing:

There’s nothing earth shattering here: upon receiving a ConnectedNotification a call is made to subscribe to the topic /hostname/cpu/temperature/value (where hostname is obtained from the OS). Now when the broker receives a message published to this topic it will broadcast it to our client. This is the pub-sub pattern in action.

This Transmission is Coming To You

To receive an MQTT message we need to handle the MQTTDelegate method func mqtt(mqtt: MQTT, didReceiveMessage message: MQTTMessage, id: UInt16 ). This can be readily accomplished using an NSNotification with accompanying userInfo:

Unfortunately for us much the userInfo dictionary remains grounded in using NSObjects as keys, so care must taken to cast String as an NSString when assembling.

In the main.swift implementation we listen for a MessageNotification:

For details on the MQTTMessage class, see the source, but we can gather from the above that two properties are of interest here:

  • topic:String – the topic to which the message was delivered
  • string:String? – the message contents, if any, delivered as a String

Get the Code

MQTTSub is an example implementation of an MQTT client that subscribes to our CPU temperature topic. Obtain it and compile with:

# git clone https://github.com/iachievedit/MQTTSub
# cd MQTTSub
# swift build
# .build/debug/MQTTSub

You will, of course, want to be running the publishing client as well:

# git clone https://github.com/iachievedit/PubSysTemp
# cd PubSysTemp
# swift build
# .build/debug/PubSysTemp

If your publishing client is running, you’ll see something like:

2016-06-13 02:55:43 +0000 - INFO    - Connecting to broker
2016-06-13 02:55:43 +0000 - INFO    - MQTT client has connected to broker.hivemq.com:1883
2016-06-13 02:55:43 +0000 - INFO    - Subscribe to topic
2016-06-13 02:55:43 +0000 - INFO    - didConnectAck
2016-06-13 02:55:43 +0000 - INFO    - didSubscribeTopic /darthvader/cpu/temperature/value
2016-06-13 02:55:44 +0000 - INFO    - Received 33.0 for topic /darthvader/cpu/temperature/value

If you want to have fun, try stress testing your system while running the publisher and subscriber. After stress -c 8 was started up:

PubSysTemp

2016-06-13 03:04:55 +0000 - INFO    - Published temperature to 34.0
2016-06-13 03:05:05 +0000 - INFO    - Published temperature to 37.0
2016-06-13 03:05:15 +0000 - INFO    - Published temperature to 42.0
2016-06-13 03:05:25 +0000 - INFO    - Published temperature to 45.0
2016-06-13 03:05:35 +0000 - INFO    - Published temperature to 47.0

MQTTSub

2016-06-13 03:04:55 +0000 - INFO    - Received 34.0 for topic /darthvader/cpu/temperature/value
2016-06-13 03:05:05 +0000 - INFO    - Received 37.0 for topic /darthvader/cpu/temperature/value
2016-06-13 03:05:15 +0000 - INFO    - Received 42.0 for topic /darthvader/cpu/temperature/value
2016-06-13 03:05:25 +0000 - INFO    - Received 45.0 for topic /darthvader/cpu/temperature/value
2016-06-13 03:05:35 +0000 - INFO    - Received 47.0 for topic /darthvader/cpu/temperature/value

What’s Next?

If you peruse the MQTT library you’ll notice it is lacking SSL support. That’s what’s next! In addition, we’ll be looking at writing additional MQTT tutorials that explore constructing topic hierarchies, using MQTT with real-world sensors, home automation devices, and more.

Leave a Reply

Your email address will not be published. Required fields are marked *