Mallow's Blog

IoT in Rails with AWS & MQTT

In our previous post we had seen how to setup IoT in AWS and we created the certificate and policy and downloaded the credentials(Certificate file, Private key, Public key and Root CA certificate) which are going to use it here to connect MQTT with AWS.

Overview of protocols:

The protocols are used by things (T) and servers (S) to interact and share data. Below are some of the protocols widely used in IoT:

MQTT: a protocol for collecting device data and communicating it to servers. This protocol is mainly used for the interaction between the server and the things (T<->S) which is what we are going to discuss in this blog.

XMPP: a protocol best for connecting devices to people, a special case of the (T<->S) pattern, since people are connected to the servers

DDS: a fast bus for integrating intelligent machines, mainly used for communication between the things (T<->T).

AMQP: a queuing system designed to connect servers to each other mainly used for communication between servers (S<->S).

What is MQTT and why it is most widely used?

MQTT stands for Message Queuing Telemetry Transport. It is publish-subscribe based, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” (M2M) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

Quality of Service(QoS):

The QoS ensures the delivery of the content to the receiver the use of the QoS levels are solely based on our need. Mostly, the QoS-1 is preferred as it handles retransmission of data for guaranteed transmission at least once to the receiver. The 3 levels of QoS:

Qos-0 – At most once delivery: In this the response is not expected and no retry semantics are defined in the protocol. A QoS-0 message can get lost if the client unexpectedly disconnects or if the server fails.

QoS-1 – At least Once Delivery: For this level of service, the MQTT client or the server would attempt to deliver the message at-least once. But there can be a duplicate message.

QoS-2 – Exactly once delivery: This is the highest level of Quality of Service. The message is delivered once and only once when QoS-2 is used.

Using MQTT in Rails with AWS:

As, we have setup everything for using MQTT with AWS now, lets use those credentials we downloaded from the generated certificate to connect to AWS IoT.

https://gist.github.com/mgokul595/855925ae9b165e8e88b500c6dc9e5cde#file-mqtt_gem_install-rb

Connecting the MQTT client:

After installing the ‘mqtt’ gem initialize the MQTT::Client with the credentials (certificate file, private key file and the root CA certificate file) that we have generated in the Step 2 of AWS IoT setup that we discussed in the blog Getting started with AWS IoT.

Host is the REST API endpoint (Ex: abcedefghijkl.iot.us-west-2.amazonaws.com) of the thing we created in Step 1 of AWS IoT setup. We can copy this endpoint by clicking the IoT thing from the AWS IoT console.

https://gist.github.com/mgokul595/c207f8b002104ac1420b5db83a0f2cd5#file-mqtt_connect-rb

Now, you can publish and subscribe to a topic to send and receive the payload.

Payload:
Here, payload is nothing but the data that we are going to publish to a topic.

Publishing:
After connecting the client we can publish the payload to the topic with just one command as below:

https://gist.github.com/mgokul595/088d91a0fef6680e2a55ac4cc5ad3af4#file-mqtt_publish-rb

Subscribing :
To subscribe to a topic just use the “subscribe” method with topic as the argument. Separate the topics by comma(,) to subscribe to multiple topics.

https://gist.github.com/mgokul595/088d91a0fef6680e2a55ac4cc5ad3af4#file-mqtt_subscribe-rb

For simulating this MQTT publish-subscribe we can use the MQTT.fx tool and create a connection profile in the tool with the credentials we downloaded from AWS as shown in the screen:

MQTT AWS Screenshot

 

As we have successfully implemented a MQTT client with AWS IoT credentials and performed publish-subscribe. In the upcoming blog we will be learning how to use AWS::IoTDataPlane instead of MQTT::Client.

Gokul,
ROR Junior Developer,
Mallow Technologies.

6 Comments

  1. Richard

    Awesome tutorial! Thanks very much!

    However, I am trying to find best practices for using MQTT in Rails in the most reusable fashion. Would you be able to assist in clearing some things up for me?

    I am confused about the following:

    1. Where is the best/most reusable place to package the connection functionality?
    2. How does one read from the queue constantly (in the background) in order to process incoming messages?

    Thanks very much!

    1. Gokul

      Hi Richard,

      1. You can create service object for MQTT in Rails and use it wherever you need.

      2. You can create a background job to process the messages in queue.

      If you are using AWS then, processing messages in background is simple as you can create an AWS::IoTRule to subscribe to a topic and you can send the messages to SQS from which you can process in background as described in this post: http://blog.mallow-tech.com/2016/11/iot-in-rails-with-aws-iot-data-plane/

      Hope it helps.

  2. Sekhar Beri

    Hi Gokul,
    This is sekhar, I have been working with mqtt and rails from past six months. I have used both in couple of projects. Upto now i have placed connection object creation and suscribuing to the topics in scheduler. i have done this because i have to suscribe to the topics when the application was initialized. Your solution that creating a connection object in a service method is good.
    Can you help me, how can i use your solution in my problem?

    1. Gokul

      Hi Sekhar Beri,

      Sorry for delayed reply.

      Services are the to keep common/reusable piece of code and in your case you can create a service object with the topic subscription related codes and use it wherever needed in your rails app like initializer or any other places.

  3. Mert

    Hi Gokul,

    As you mentioned earlier, when a message is received from a subscribed topic, I’m planning to create a job to handle it. However, I didn’t understand how I should create client object. Can I use a single client everywhere (as service object) or should I create a client for each user logged in to my Rails app? Thanks in advance.

    1. Gokul

      Hi Mert,

      Thanks for your comment.

      This should be decided based on you requirement.

      If you just need a client and that act common for all users then you no need to create a new object for every user, you can create a client in initializer and user it all over the app.
      In other case if you have a service object which initialize the MQTT client and also contains some user specific detail then you need to create a new object every time.

      I think you can create an client object in initializer and use it everywhere.

      Hope it helps.

      Don’t hesitate to ask further details / doubts.

Leave a Comment

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