The HTML canvas is a powerful widget that allow Ubidots users to create specialized mini-web apps using Ubidots' API REST and a little imagination. With the HTML canvas, users can create presentation user layers (UX) like customized maps or animated business apps

The HTML canvas is best utilized with a programmed GET request that fits our API REST, but if you need to show real-time values from different variables using many widgets, a 429 response error might be standing in your way. For server security reasons Ubidots does not allow users to receive hundred of instant requests from a single device. This is a headache if you wish to develop a customized dashboard using only HTML canvas widgets to show values in real time. Do not worry, Ubidots is here to help you bypass this 429 Error with ease. In this tutorial will demonstrate how to implement a quick real-time HTML widget using the socket.IO JS library.
 
NOTE: This article is intended to be read by user with knowledge of HTML, JS and CSS. If you are not familiar with these languages we strongly advise brushing up on the basics and return to this article once you are feeling more comfortable to code.

Socket.IO

Socket.IO is a JS library easy to implement that manages socket connections and messages, thus enabling a bi-directional real-time connection protocol. Ubidots has implemented this protocol within its core servers to easily update devices using sockets to retrieve and store data inside any JS variable, without need of implementing requests, and in real-time.

Architecture

To implement a bi-directional TCP connection using socket.IO you must first publish the variable's ID that you wish to "listen" to in real-time with Ubidots. Once you've published to Ubidots' server which variable you wish to listen, Ubidots will reply with a packet each time that the variable is updated (you do not need to ask to the server for values, it will send the updated variable to you automatically). Below you can find a helpful diagram of how the listening connection works:

The client publishes the variable ID that wishes to constantly monitor or "listen." If there is an update to that variable the server will update every subsequent TCP client. The main advantage of this architecture is the always connected and listening server with the Main DB. The main process is implemented by the server and not the browser, resulting in a lightweight communication protocol using socket.IO.

Endpoints:

Below you will find the two endpoints to implement a TCP connection to Ubidots' server using socket.IO:

  • To publish the desired variable to listen:

https://industrial.ubidots.com:443/notifications/rt/variables/id/last_value 

  •  To un-subscribe for listening a variable:

https://industrial.ubidots.com:443/notifications/unsub/rt/variables/id/last_value

Coding

The HTML Canvas widget is divided into three main coding slots: HTML, CSS and JS, I will not implement any CSS as this tutorial is not intended for the widget's visual design, so we will work only with some of HTML and JS.

HTML

<p id="content"></p>

The HTML is pretty simple for this exchange; we will update a paragraph meta-tag that shows us the data received from the socket.

 JS

var socket;
var srv = "industrial.ubidots.com:443";
var VAR_ID = "5a0f6e7a76254211cac86bea"; // Put here your var Id
var TOKEN = "..."  // Put here your token
$( document ).ready(function() {
// Implements the connection to the server
socket = io.connect("https://"+ srv, {path: '/notifications'});
var subscribedVars = [];

// Function to publish the variable ID
var subscribeVariable = function (variable, callback) {
  // Publishes the variable ID that wishes to listen
  socket.emit('rt/variables/id/last_value', {
    variable: variable
  });
  // Listens for changes
  socket.on('rt/variables/' + variable + '/last_value', callback);
  subscribedVars.push(variable);
};

// Function to unsubscribed for listening
var unSubscribeVariable = function (variable) {
  socket.emit('unsub/rt/variables/id/last_value', {
    variable: variable
  });
  var pst = subscribedVars.indexOf(variable);
  if (pst !== -1){
    subscribedVars.splice(pst, 1);
  }
};

var connectSocket = function (){

  // Implements the socket connection
  socket.on('connect', function(){
    socket.emit('authentication', {token: TOKEN});
  });
  window.addEventListener('online', function () {
    socket.emit('authentication', {token: TOKEN});
  });
  socket.on('authenticated', function () {
    subscribedVars.forEach(function (variable_id) {
      socket.emit('rt/variables/id/last_value', { variable: variable_id });
    });
  });
}

/* Main Routine */

connectSocket();

// Subscribe Variable with your own code.
subscribeVariable(VAR_ID, function(value){
  var parsedValue = JSON.parse(value);
  console.log(parsedValue);
  $('#content').text(value);
  })
});

The JS code will make use of the socket.IO library. To breakdown the code to better explain its structure we have divided it into 5 parts to better explain:

var socket;
var srv = "industrial.ubidots.com:443";
var VAR_ID = "5a0f6e7a76254211cac86bea"; // Put here your var Id
var TOKEN = "..."  // Put here your token

Here we define the variables that will store the socket object, server's dns address, variable ID and your account TOKEN, nothing very impressive. FOR EDUCATIONAL USERS: please define the server as "app.ubidots.com".

// Implements the connection to the server
     socket = io.connect("https://"+ srv, {path: '/notifications'});
     var subscribedVars = [];
 
     // Function to publish the variable ID
     var subscribeVariable = function (variable, callback) {
         // Publishes the variable ID that wishes to listen
         socket.emit('rt/variables/id/last_value', {
             variable: variable
         });
         // Listens for changes
         socket.on('rt/variables/' + variable + '/last_value', callback);
         subscribedVars.push(variable);
     };

This piece of code becomes a little more interesting, using the connect() method from socket.IO we can connect to the Ubidots server using the specified endpoint.  Then, a function to publish the variable ID for listening is implemented using the emit() method and we publish to the server which variable we want to listen. With the on()  method we keep listening for any changes between the client and server. The subscribedVars array will store all the variables IDs. We will use it later to implement easily a routine to reconnect  in the case of connection lost.

// Function to unsubscribed for listening
     var unSubscribeVariable = function (variable) {
         socket.emit('unsub/rt/variables/id/last_value', {
             variable: variable
         });
         var pst = subscribedVars.indexOf(variable);
         if (pst !== -1){
             subscribedVars.splice(pst, 1);
         }
     };

This function, as its name suggests, let us to stop to listen a variable. Using again the emit() method, we notify to the server that we do not wish to listen to the specified variable anymore.

var connectSocket = function (){

    // Implements the socket connection
    socket.on('connect', function(){
        socket.emit('authentication', {token: TOKEN});
     });
    window.addEventListener('online', function () {
         socket.emit('authentication', {token: TOKEN});
     });
     socket.on('authenticated', function () {
         subscribedVars.forEach(function (variable_id) {
         socket.emit('rt/variables/id/last_value', { variable: variable_id });
         });
     });
}

The connectSocket() function lets us implement a connection routine in case we lose connection at any point. Basically, we publish again all the variables stored at the subscribedVars array and tell the server to continue listening. Using the JS method for listening events, once the client or the socket is connected we emit the authentication credentials to keep listening for changes in our variables.

Important note: Due to the asynchronous paradigm of JS, we use the on() method from socket.IO to know when the socket is opened for sending the authentication credentials.

/* Main Routine */

connectSocket();

// Subscribe Variable with your own code.
subscribeVariable(VAR_ID, function(value){
    var parsedValue = JSON.parse(value);
    console.log(parsedValue);
        $('#content').text(value);
     })
});

With all our connection functioning now, the main routine becomes pretty simple, after the connection routine we subscribe to our variable ID and simply update any paragraph meta-tag identified as "content" with the results that comes from the server.

Lastly, do not forget to import the necessary JS libraries to run this example:

Results

Below you can find the final results of our widget. In real-time, our widget is updating with all data references that come from the server (timestamp, value, variable id and context):

GOAL REACHED:

With the completed code, our real-time HTML Canvas widget now reflects on the dashboard and works great! Now it is your turn to give it a try.

Do not forget to leave us your comments in our community forums or connect with us vis social media at Facebook, Twitter or Hackster with any questions or words of support.

 

Did this answer your question?