Introduction of VerneMQ | Installation on Ubuntu

Introduction of VerneMQ | Installation on Ubuntu

7 June 2023 0 By Harshvardhan Mishra

What is VerneMQ?

VerneMQ is first and foremost a MQTT publish/subscribe message broker which implements the OASIS industry standard MQTT protocol. But VerneMQ is also built to take messaging and IoT applications to the next level by providing a unique set of features related to scalability, reliability and high-performance as well as operational simplicity.

To achieve these goals VerneMQ is designed from the ground up to work as a distributed message broker, ensuring continued operation in the event of node or network failures and easy horizontal scalability. The underlying technology is a proven telecom grade technology stack providing a rock solid foundation for systems that must be in continuous operation around the clock. It’s also able to make efficient use of all available resources as a basis for easy vertical scalability.

VerneMQ uses a master-less clustering technology. There are no special nodes like masters or slaves to consider when the inevitable infrastructure changes or maintenance windows require adding or removing nodes. This makes operating the cluster safe and simple.

What is MQTT

An open industry standard (developed by OASIS), specifying a light weight publish-subscribe messaging protocol. It is perfect for large-scale Internet of Things applications and high performance mobile messaging.

You may also like : MQTT | What is MQTT | MQTT in Depth | QoS | FAQs | MQTT Introduction

VerneMQ – The Big Picture

VerneMQ features

VerneMQ implements the full MQTT 3.1, 3.1.1 and 5.0 specifications. The current list of core features include:

  • QoS 0, QoS 1, QoS 2 levels
  • File-based Authentication and Authorization
  • PostgreSQL, MySQL, Redis & MongoDB Authentication and Authorization
  • Bridge Support
  • $SYS Tree for monitoring and reporting
  • TLS (SSL) Encryption
  • Websockets Support
  • Cluster Support
  • Logging (Console, Files, Syslog)
  • Reporting to Graphite
  • Reporting to Prometheus
  • Extensible Plugin architecture
  • Shared Subscriptions
  • Multiple Sessions per ClientId
  • Session Balancing
  • Message load regulation
  • Message load shedding (for system protection)
  • Offline Message Storage (based on LevelDB)
  • Queue can handle messages FIFO or LIFO style.
  • PROXY v2 Protocol
  • Lua plugin scripting support
  • Webhooks
  • HTTP Administration API

Application of VerneMQ

Mobile Messaging
Develop mobile messaging services with a much smaller overhead than XMPP. Open up new mobile use cases with low-latency bi-directional communication.
Connecting IoT Field Devices
Monitor and control all devices you have out there in the field. Connect them to your data centers, backend services and smartphone apps. You can trust VerneMQ to hold it all together.
Smart Infrastructure
Cities, Homes, Transportation. Mobile assets. From a small lab project to a successful industrial deployment of your solution: VerneMQ will handle your messages.

Installing on Debian and Ubuntu

Once you have downloaded the binary package, execute the following command to install VerneMQ:

sudo dpkg -i vernemq-<VERSION>.bionic.x86_64.deb

Note: Replace bionic with appropriate OS version such as focal/trusty/xenial.

Verify your installation

dpkg -s vernemq | grep Status
If VerneMQ has been installed successfully Status: install ok installed is returned.
Activate VerneMQ node
Once you’ve installed VerneMQ, start it on your node:
service vernemq start

Default Directories and Paths

The whereis vernemq command will give you a couple of directories:

whereis vernemq
vernemq: /usr/sbin/vernemq /usr/lib/vernemq /etc/vernemq /usr/share/vernemq
                Path                                                         Description
/usr/sbin/vernemq:
the vernemq and vmq-admin commands
/usr/lib/vernemq
the vernemq package
/etc/vernemq
the vernemq.conf file
/usr/share/vernemq
the internal vernemq schema files
/var/lib/vernemq
the vernemq data dirs for LevelDB (Metadata Store and Message Store)

How to configure VerneMQ

Every VerneMQ node has to be configured as the default configuration probably does not match your needs. Depending on the installation method and chosen platform the configuration file vernemq.conf resides at different locations. If VerneMQ was installed through a Linux package the default location for the configuration file is /etc/vernemq/vernemq.conf.
General Format of the vernemq.conf file
  • A single setting is handled on one line.
  • Lines are structured Key = Value
Any line starting with # is a comment, and will be ignored.
Minimal Quickstart Configuration
You certainly want to try out VerneMQ right away. To just check the broker without configured authentication for now, you can allow anonymous access:
  • Set allow_anonymous = on

By default the vmq_acl authorization plugin is enabled and configured to allow publishing and subscribing to any topic (basically allowing everything), check the for more information.

Note : Setting allow_anonymous=on completely disables authentication in the broker and plugin authentication hooks are never called! Find the details on all the authentication hooks

Getting Started with VerneMQ

As MQTT is the main application protocol spoken by VerneMQ, you could use any protocol compliant MQTT client library. This page gives an overview of the different options you have.

Platform specific libraries:

C

We recommend the Mosquitto C library. A simple example looks like the following:

    #include <stdio.h>
    #include <mosquitto.h>

    /* Compile with: cc -o sub sub.c -lmosquitto  */

    void on_connect(struct mosquitto *mosq, void *userdata, int rc)
    {
        mosquitto_subscribe(mosq, NULL, "$SYS/#", 0);
    }

    void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *m)
    {
        printf("%s %s\n", m->topic, m->payload);
    }

    int main(int argc, char **argv)
    {
        struct mosquitto *mosq;
        int rc;

        mosquitto_lib_init();

        mosq = mosquitto_new(NULL, true, (void *)NULL);
        if (!mosq) {
            fprintf(stderr, "Error: Out of memory.\n");
            mosquitto_lib_cleanup();
            return (1);
        }

        mosquitto_connect_callback_set(mosq, on_connect);
        mosquitto_message_callback_set(mosq, on_message);

        rc = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);
        if (rc) {
            fprintf(stderr, "Unable to connect (%d).\n", rc);
            mosquitto_lib_cleanup();
            return (rc);
        }

        mosquitto_loop_forever(mosq, -1, 1);

        /* Unreached */
        mosquitto_destroy(mosq);
        mosquitto_lib_cleanup();

        return (0);
    }

C++

We recommend the official Paho MQTT client library. A simple example looks like the following:

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    int rc = 0;
    char buf[200];
    MQTTString topicString = MQTTString_initializer;
    char* payload = "mypayload";
    int payloadlen = strlen(payload);int buflen = sizeof(buf);

    data.clientID.cstring = "me";
    data.keepAliveInterval = 20;
    data.cleansession = 1;
    len = MQTTSerialize_connect(buf, buflen, &data);

    topicString.cstring = "mytopic";
    len += MQTTSerialize_publish(buf + len, buflen - len, 0, 0, 0, 0, topicString, payload, payloadlen);

    len += MQTTSerialize_disconnect(buf + len, buflen - len);

    rc = Socket_new("127.0.0.1", 1883, &mysock);
    rc = write(mysock, buf, len);
    rc = close(mysock);

Java

We recommend the official Paho MQTT client library. A simple example looks like the following:

    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

    public class MqttPublishSample {

        public static void main(String[] args) {

            String topic        = "MQTT Examples";
            String content      = "Message from MqttPublishSample";
            int qos             = 2;
            String broker       = "tcp://iot.eclipse.org:1883";
            String clientId     = "JavaSample";
            MemoryPersistence persistence = new MemoryPersistence();

            try {
                MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
                MqttConnectOptions connOpts = new MqttConnectOptions();
                connOpts.setCleanSession(true);
                System.out.println("Connecting to broker: "+broker);
                sampleClient.connect(connOpts);
                System.out.println("Connected");
                System.out.println("Publishing message: "+content);
                MqttMessage message = new MqttMessage(content.getBytes());
                message.setQos(qos);
                sampleClient.publish(topic, message);
                System.out.println("Message published");
                sampleClient.disconnect();
                System.out.println("Disconnected");
                System.exit(0);
            } catch(MqttException me) {
                System.out.println("reason "+me.getReasonCode());
                System.out.println("msg "+me.getMessage());
                System.out.println("loc "+me.getLocalizedMessage());
                System.out.println("cause "+me.getCause());
                System.out.println("excep "+me);
                me.printStackTrace();
            }
        }
    }

Golang

We recommend the official Paho MQTT client library. A simple example looks like the following:

    package main

    import (
      "fmt"
      //import the Paho Go MQTT library
      MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
      "os"
      "time"
    )

    //define a function for the default message handler
    var f MQTT.MessageHandler = func(msg MQTT.Message) {
      fmt.Printf("TOPIC: %s\n", msg.Topic())
      fmt.Printf("MSG: %s\n", msg.Payload())
    }

    func main() {
      //create a ClientOptions struct setting the broker address, clientid, turn
      //off trace output and set the default message handler
      opts := MQTT.NewClientOptions().SetBroker("tcp://iot.eclipse.org:1883")
      opts.SetClientId("go-simple")
      opts.SetTraceLevel(MQTT.Off)
      opts.SetDefaultPublishHandler(f)

      //create and start a client using the above ClientOptions
      c := MQTT.NewClient(opts)
      _, err := c.Start()
      if err != nil {
        panic(err)
      }

      //subscribe to the topic /go-mqtt/sample and request messages to be delivered
      //at a maximum qos of zero, wait for the receipt to confirm the subscription
      if receipt, err := c.StartSubscription(nil, "/go-mqtt/sample", MQTT.QOS_ZERO); err != nil {
        fmt.Println(err)
        os.Exit(1)
      } else {
        <-receipt
      }

      //Publish 5 messages to /go-mqtt/sample at qos 1 and wait for the receipt
      //from the server after sending each message
      for i := 0; i < 5; i++ {
        text := fmt.Sprintf("this is msg #%d!", i)
        receipt := c.Publish(MQTT.QOS_ONE, "/go-mqtt/sample", text)
        <-receipt
      }

      time.Sleep(3 * time.Second)

      //unsubscribe from /go-mqtt/sample
      if receipt, err := c.EndSubscription("/go-mqtt/sample"); err != nil {
        fmt.Println(err)
        os.Exit(1)
      } else {
        <-receipt
      }

      c.Disconnect(250)
    }

Lua

We recommend the mqtt_lua client library. The library requires A simple example looks like the following:

    -- Define a function which is called by mqtt_client:handler(),
    -- whenever messages are received on the subscribed topics

      function callback(topic, message)
        print("Received: " .. topic .. ": " .. message)
        if (message == "quit") then running = false end
      end

    -- Create an MQTT client instance, connect to the MQTT server and
    -- subscribe to the topic called "test/2"

      MQTT = require("mqtt_library")
      MQTT.Utility.set_debug(true)
      mqtt_client = MQTT.client.create("localhost", nil, callback)
      mqtt_client:connect("lua mqtt client"))
      mqtt_client:subscribe({"test/2"})

    -- Continously invoke mqtt_client:handler() to process the MQTT protocol and
    -- handle any received messages.  Also, publish a message on topic "test/1"

      running = true

      while (running) do
        mqtt_client:handler()
        mqtt_client:publish("test/1", "test message")
        socket.sleep(1.0)  -- seconds
      end

Python

We recommend the official Paho MQTT client library. A simple example looks like the following:

    import paho.mqtt.client as mqtt

    # The callback for when the client receives a CONNACK response from the server.
    def on_connect(client, userdata, rc):
        print("Connected with result code "+str(rc))
        # Subscribing in on_connect() means that if we lose the connection and
        # reconnect then subscriptions will be renewed.
        client.subscribe("$SYS/#")

    # The callback for when a PUBLISH message is received from the server.
    def on_message(client, userdata, msg):
        print(msg.topic+" "+str(msg.payload))

    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_message = on_message

    client.connect("iot.eclipse.org", 1883, 60)

    # Blocking call that processes network traffic, dispatches callbacks and
    # handles reconnecting.
    # Other loop*() functions are available that give a threaded interface and a
    # manual interface.
    client.loop_forever()

Ruby

We recommend the Ruby-MQTT client library. A simple example looks like the following:


    require 'rubygems'
    require 'mqtt'

    # Publish example
    MQTT::Client.connect('myserver.example.com') do |c|
      c.publish('topic', 'message')
    end

    # Subscribe example
    MQTT::Client.connect('myserver.example.com') do |c|
      # If you pass a block to the get method, then it will loop
      c.get('test') do |topic,message|
        puts "#{topic}: #{message}"
      end
    end

Javascript

We recommend the official Paho MQTT client library. This library is meant to be used in the web browser. It requires that VerneMQ has a websocket listener configured. A simple example for using the client on a webpage could look like the following:

    // Create a client instance
    client = new Paho.MQTT.Client(location.hostname, Number(location.port), "clientId");

    // set callback handlers
    client.onConnectionLost = onConnectionLost;
    client.onMessageArrived = onMessageArrived;

    // connect the client
    client.connect({onSuccess:onConnect});


    // called when the client connects
    function onConnect() {
      // Once a connection has been made, make a subscription and send a message.
      console.log("onConnect");
      client.subscribe("/World");
      message = new Paho.MQTT.Message("Hello");
      message.destinationName = "/World";
      client.send(message); 
    }

    // called when the client loses its connection
    function onConnectionLost(responseObject) {
      if (responseObject.errorCode !== 0) {
        console.log("onConnectionLost:"+responseObject.errorMessage);
      }
    }

    // called when a message arrives
    function onMessageArrived(message) {
      console.log("onMessageArrived:"+message.payloadString);
    }

PHP

We recommend the phpMQTT client library. A simple example looks like the following:

    <?php
    require("../phpMQTT.php");

    $mqtt = new phpMQTT("example.com", 1883, "phpMQTTClient");
    if(!$mqtt->connect()){
        exit(1);
    }

    // Simple Publish Example
    $mqtt->publish("test/topic/example/","Hello World!", 0);


    // Simple Subscribe Example
    $topics['test/topic/example'] = array("qos" => 0, "function" => "procmsg");
    $mqtt->subscribe($topics,0);
    while($mqtt->proc()){
        // receive loop
    }

    $mqtt->close();

    function procmsg($topic, $msg){
        echo "Msg Recieved: ".date("r")."\nTopic:{$topic}\n$msg\n";
    }
    ?>

Android

In principle it is possible to use the Paho Java library directly for this, but a much better option is to use Paho Android Client and Service which wraps the java library in an Android Service which makes it easy to send and receive messages on behalf of Android applications, even when they are not currently running.

iOS

In principle it is possible to wrap a C library and get it to work on iOS, but since Apple does not permit third party networking stacks access to the mobile antenna we recommend the native Objective-C MQTT-Client-Framework.

Arduino

We recommend the knolleary MQTT client library. The library requires the Arduino Ethernet Shield. A simple example looks like the following:

    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>

    // Update these with values suitable for your network.
    byte mac[]    = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
    byte server[] = { 172, 16, 0, 2 };
    byte ip[]     = { 172, 16, 0, 100 };

    void callback(char* topic, byte* payload, unsigned int length) {
      // handle message arrived
    }

    EthernetClient ethClient;
    PubSubClient client(server, 1883, callback, ethClient);

    void setup()
    {
      Ethernet.begin(mac, ip);
      if (client.connect("arduinoClient")) {
        client.publish("outTopic","hello world");
        client.subscribe("inTopic");
      }
    }

    void loop()
    {
      client.loop();
    }

For more details : https://docs.vernemq.com

Suggested Readings!