Create Your MQTT Hello World

MQTT provides a flexible lightweight publish/subscribe protocol that enables messaging in IoT applications.  For this exercise, you need to connect your development computer via SSH to the SmartServer, and set a rule to enable MQTT traffic from external MQTT clients.  You will write a simple node.js application that will publish a message as an MQTT client.

Before beginning this exercise, you will need to connect your development computer and the SmartServer through a switch to a LAN that will provide IP addresses using DHCP.   Your computer should support mDNS (Multicast DNS, often referred to as zeroconf, or Bonjour).  You can confirm that your PC has the Bonjour service installed by launching the Services applet and looking for the Bonjour Service.  If not installed, go to this link to install the service (https://support.apple.com/kb/DL999?locale=en_US).

Connect to the SmartServer

Instructions for connecting to the SmartServer are provided in Step 2 - Connect to Your SmartServer IoT.  Once you have connected and logged in to the SmartServer using SSH in a Console window, you can continue with enabling the Firewall for MQTT.

Enable the Firewall for MQTT

  1. MQTT uses TCP port 1883.  Determine whether this port will be passed by the firewall by typing the shell command:  sudo ufw status   

    This command provides a list of ports along with the keywords ALLOW and Anywhere for each port that is passed by the firewall.




  2. If port 1883 is not in the list of allowed ports, then type: sudo ufw allow 1883, followed by sudo ufw status  to confirm that 1883 is now listed as one of the allowed ports.

    Opening port 1883 allows you to run your node application on your development computer, and have access to the source level debugger on that machine. Once the application is deployed for production, you may want to delete this rule for security purposes.





  3. To establish the IP address assigned to your SmartServer that is connected to your network using the eth0 port, type:  ifconfig eth0   

    When using the ifconfig command from the console, either log in as root or enter sudo ifconfigSee Step 2 - Connect to Your SmartServer IoT

    Your IP address is displayed as inet.  Make a note of this IP address as you will use it multiple times throughout this tutorial. 



    Do not close your SSH session, as you will use it again during the next example.

Create the helloMqtt.js Program

In this next example, we will write an application that publishes a message from your development machine that appears on the console of the SmartServer target.  In this application, the npm mqtt.js package is used.  The SmartServer includes the mosquito message broker (https://mosquitto.org/).  This library includes two useful clients, mosquitto_sub and mosquitto_pub, which are used in this example. 

  1. In VS Code, while in the folder you created in step 2 of the previous exercise, select File > New File      

  2. Select File > Save As and name this new file helloMqtt.js 
    This creates the helloMqtt.js file in the folder you created for your exercises.

  3. In the terminal pane of VS Code, type: npm init  
    This command prompts you to provide a variety of information for the application you're developing.  For this exercise, you can provide the entries highlighted by the green boxes in the following screenshot.  Note that the name entry must be in lower case characters. 




  4. After entering the values, type yes to the prompt Is this ok? 
    This creates a package.json file for the application that will eventually be used for deployment. 

  5. Our application uses mqtt.js, so in the VS Code Terminal pane, type: npm install mqtt −−save  
    This package provides the support of MQTT, and the --save option causes npm to add the mqtt module dependency to your package.json, and will create a package-lock.json, which documents the packages needed for the mqtt.js package.

  6. To run the application on your development computer, and eventually on the SmartServer, you need to add information to the launch.json file located in the .vscode subdirectory.  You can edit launch.json in VS Code, by selecting View > Explorer  and then selecting launch.json from the Explorer tree under the .vscode branch.
    This opens launch.json for editing.

  7. You must edit your launch.json file to match the code sample shown below.  Specifically, ensure that program (line 11) includes helloMqtt.js, and add the environment variable DEV_TARGET (line 12), but be sure to replace the Xs with your SmartServer's IP address. 

        "configurations": [
            {
                "type": "node",
                "request": "launch",
                "name": "Launch Program",
                "program": "${workspaceFolder}\\helloMqtt.js",
                "env":{"DEV_TARGET":"X.X.X.X"}
            }
        ]
  8. Save your changes to launch.json.
  9. Open the helloMqtt.js file created in step 2, and add the following block of code. 
    Line 1 of the code will pull in the npm mqtt module, which does all the MQTT work.  The connect event will set up a topic that this application subscribes to, and will publish a message to the same topic:  Dave

    helloMqtt.js Source Code
    var mqtt = require('mqtt');
    
    /* environ returns the value of a named environment
     * variable, if it exists, or returns the default
     * value otherwise.
     */
    function environ(variable, defaultValue) {
        return process.env.hasOwnProperty(variable) ?
            process.env[variable] : defaultValue;
    }
    //  Set up an MQTT client for the duration of the app lifetime.
    const client = mqtt.connect(
        'mqtt://' + environ('DEV_TARGET', '127.0.0.1') + ':1883'
    );
    // Module level variables 
    const myPid = process.pid;
    // A simple message object that includes the instance PID to distinquish messages
    var sendMsg = {
        msg: 'Hello Dave',
        pid: myPid
    };
    var greetings = 0;
    
    client.on(
        'connect', 
        () => { 
            console.log ('My PID: ' + myPid);
            client.subscribe('Dave'); 
            client.publish(
                'Dave',                 // topic
                JSON.stringify(sendMsg) // serialize the sendMsg object
            );
        } //on_connect handler
    );
    
    client.on(
        'message',
        (topic, message) => {
            var rcvdMsg = JSON.parse(message);
            console.log( topic + ': <-- ' +  rcvdMsg.msg + 
                ' from: ' + rcvdMsg.pid + ' msgCnt: ' + greetings);
            if (rcvdMsg.pid != myPid) { // respond to messages form others
                if (!client.disconnecting) {
                    client.publish('Dave', JSON.stringify(sendMsg));
                    ++greetings;
                    console.log( topic + ': --> ' +  sendMsg.msg + ' msgCnt: ' + greetings);
                }
                // Reached the 4 messge threshold. 
                if (greetings > 4) {
                    sendMsg.msg = 'Goodbye'
                    client.publish ('Dave', JSON.stringify(sendMsg));
                    client.end (
                        false,
                        () => {
                            console.log('Exiting now.');
                            process.exit();
                        }
                    );
                };
             }; // resp to message from others
        } //on_message handler
    );
    client.on (
        'error',  
        (error) => {
            console.log ('I can\'t do that Dave. Error: ' + error.message);
            process.exit();
        }
    );
  10. From the SSH Terminal session on the SmartServer, type:  mosquitto_sub Dave
    This command subscribes to the Dave topic.  At this point, there is no visible response in the SSH Terminal to the command.

    Topic Case Sensitivity

    Topics in mqtt and the IAP/MQ API are case sensitive. In this example, the topic Dave starts with a capitol "D". Subscribe to dave and you won't receive messages.

  11. In VS Code, select Debug > Open Configurations and verify the program target is helloMqtt.js and that you have defined the DEV_TARGET environment variable.




  12. Run the application using the VS Code debugger as described in the last example
    Each time the application connect event occurs, the application will subscribe to the topic Dave, a greeting message will be published (see lines 24-34 in the above code), and the output from the mosquitto_sub client will appear as shown in the following screenshot:




  13. Create a second Terminal console connection to your SmartServer as user apollo, and type this command (be very careful when entering the −m json encoded message):  mosquitto_pub t Dave m '{"msg":"Cheers","pid":1}'  

  14. The next screenshot captures the sequence of executing the previous step several times.  Notice how the VS code messages show that this application is publishing messages to the topic Dave, and it is also receiving the messages because it also subscribes to the topic Dave.



Congratulations you have written an application that uses MQTT to communicate between your development computer and your target SmartServer.  

Next Step

Now that you have created your MQTT Hello World, you can move on to the next step in this tutorial:  Run the helloMqtt App on the SmartServer