Setting up MQTT with Ruby on Rails
Tags: mqtt, ruby, rails
Published: 2020-03-22 11:59:24

###**Introduction to MQTT**
 **MQTT** is a Client-Server publish, subscribe messaging transport protocol. It is lightweight, open, simple, and designed to be easy to implement. These qualities make it ideal for use in many spots, including constrained environments such as for communication in Machine to Machine (M2M) and Internet of Things (IoT) world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

**Why the adoption of MQTT ?**
Well, as opposed to HTTP it is an extremely light-weight protocol. HTTP is stateless and thus a new connection needs to be established for every request (communication overhead). MQTT is based on data streams that stay connected once they are established (minimal overhead). This makes MQTT faster for sending data very frequently as is common for IoT use cases.

A protocol for collecting device data and communicating it to servers.
In addition, it is very easy to have multiple applications consume different sets of data. Each application can simply subscribe to the data points they need. As simple as that…

But, that’s enough introduction. Let’s take a look at how to set up such a process to connect and how you get your data there.

###**MQTT Basic Concepts:**

**Publishers**- publish messages to the broker.
**Subscribers**- subscribe to a particular topic with the broker.
**Broker**- ensures correct routing of messages published to it by the publishers, to the correct subscriber(s).
**Topics**- can be thought of as naming specific sets of data. It’s generally a plain string, usually corresponds to a legit word in English for ease of use. A publisher would essentially publish data on one of the topics. Similarly, a subscriber can subscribe to a particular topic. The job of the broker is to route messages based on the topic.

###**How to set up an MQTT broker with rails:**

You may get the latest stable version from Rubygems:
```ruby
gem install mqtt
```

Alternatively, to use a development snapshot from GitHub using Bundler:

```ruby
gem 'mqtt', :git => 'https://github.com/njh/ruby-mqtt.git'
```

####**1. Connecting to server**

A new client connection can be created by passing either an MQTT URI, a host and port or by passing a hash of attributes.

Here some ways to connect sever:

```ruby
#using MQTT URI
client = MQTT::Client.connect("mqtt://servername.example.com")

#using server name with passing host and port
client = MQTT::Client.connect(:host => "servernamer.example.com", :port => 8080 ... )

#Enabled SSL connection 
client = MQTT::Client.connect(
  :host => "servernamer.example.com",
  :port => 8080,
  :ssl => true
)

#NOTE: if you have set up everything for using MQTT with AWS, let’s use those credentials we downloaded from the generated certificate to connect to AWS IoT.

#using client certificate-based authentication when passing below attributes

client = MQTT::Client.connect(
        host: "myserver.example.com", # Your AWS  IoT host
        port: 8883,
        ssl: true,
        cert_file:  #path_to('client.pem')
        key_file: #path_to('client.key')
        ca_file:  #path_to('root-ca.pem')”
    )
```

####**2. Publishing**

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

```ruby
topic = "mqtt/test"

payload = { test: "This test message."}.to_json

# Publish to the topic
client.publish(topic, payload, retain=false, qos=1)
```

####**3. Subscribing**
You can send a subscription request to the MQTT server using the subscribe method. 
To subscribe to a topic just use the “subscribe” method with the topic as the argument. Separate the topics by comma(,) to subscribe to multiple topics.

```ruby
    client.subscribe("topic1")
    client.subscribe("topic1", "topic2")
    client.subscribe("test/#")
```

####**4. Receiving Messages:**

To receive a message, use the get method. This method will block until a message is available. The topic is the name of the topic the message was sent to. The message is a string:

```ruby
topic, message = client.get

# To receive a message from a topic:
  client.get do |topic, message|
     # Block is executed for every message received
  end
```

As you have successfully implemented an MQTT client with performed publish-subscribe to received data.

I hope you found it as easy as I did to make this work.

Thank you for reading!!!