Thursday, June 11, 2015

Real-Time Web Interface to MQTT using Socket.io and Node.js

First, all credit for this tutorial goes to Robert Hekkers Blog.  I've altered it slightly to pick up newer versions of the various javascript libraries.

If you've followed along with my earlier post, you now have MQTT running on your Raspberry Pi, and an Arduino IoT client that can publish and subscribe to MQTT packets.  The next step is developing a real-time web interface that can control your MQTT network.

Why Socket.io and Node.js?
Web browsers typically operate by pulling data from a server when you click on a link.  Servers don't usually keep an open connection to the browsers it has serviced, so if some event happens on the server side, the server cannot push that event to your browser, unless you refresh the page.

That's where Socket.io comes in handy.  Socket.io maintains an open connection between the server and the browser, which enables the server to push updates to the browser as they happen.  This is useful so you can see changes to your IoT network as they happen, and not have to wait for a page refresh.

Step 1: Setup a Web Server on your Raspberry Pi
sudo apt-get install apache2 -y
hostname -I
Now test your web server by using a web browser to navigate to your Raspberry Pi's web address










Step 2: Get Socket.IO, Node.js and the MQTT client
wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb
sudo apt-get install npm

cd /var/www
sudo npm install mqtt
sudo npm install socket.io


Step 3: Test Your Node.js and MQTT client
create the file /var/www/mqtt_test.js
node mqtt_test.js
Then change the server URL from test.mosquitto.org to your Rpi's IP address
node mqtt_test.js

Step 4: Get Thomas Reynolds' iOS Style Jquery Checkboxes
cd ~/
wget https://github.com/tdreyno/iphone-style-checkboxes/archive/v1.zip
unzip v1.zip
cd iphone-style-checkboxes-1
sudo cp -pr jquery /var/www
sudo cp -pr images /var/www
sudo cp style.css /var/www


Step 5: Create a Node.js script to link Socket.io to MQTT
create the file /var/www/pusher.js
node pusher.js &

Step 6: Create your web page
create the file /var/www/iot_demo.html

Step 7: Test your real-time web interface
mosquitto_sub -t "led"
browse to http://your_rpi_ip_address/iot_demo.html
toggle the checkbox, and you should see messages on your MQTT network Now open multiple browsers and try toggling the checkbox

15 comments:

  1. Hi, Nice to meet you.
    My name is Justin, at WIZnet in Korea. We have been searching some application references in which WIZnet solution is applied, and found your project using Ethernet Shield. In the Ethernet Shield WZnet’s W5100 chip is embedded. Your development looks very cool & smart. Recently we opened WIZnet Museum (http://wiznetmuseum.com) site. This is a academic-purposed collection of open projects, tutorials, articles and etc from our global customers.
    If you are O.K. we would like to introduce your projects in here.

    Please reply me.

    Thank you very much

    My E-mail : justinkim@wiznet.co.kr

    ReplyDelete
    Replies
    1. Justin,
      By all means, feel free to share my project!

      Delete
  2. hellow. I try to use your code to connect to cloudmqtt.com , but it is necessary to use my login and password.And server indicated not ip as the address (for example m20.cloudmqtt.com ) Prompt as me right to make changes to the code that I had everything working. Information about the cloud here. https://www.cloudmqtt.com/docs.html
    Thank you!

    ReplyDelete
  3. Hi Chuck...thanks for this post it is indeed helpfull...I am a new to node and sockets...i am not using apache webserver...I am using express(to render html) and node to create a Server.
    var app = require('express')();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    http.listen(3000, function(){
    console.log('Web server started.Listening on *:3000');
    });

    Do i need to create a socket which listens on port 5000.What if i do not specify the port. what does socket.join do?Thanks.

    ReplyDelete
  4. Hello, I am working on the same technology in IoT for which you have conducted workshop in the month of May and June. i am working on it since one and half years and now i am working on M.E.A.N. stack but now i got stcuk in binding of mqtt with socket.io so can you please provide me some details about it or any other professional charges please let me know. Thanks

    ReplyDelete
  5. Are there any problems with client side javascript communicating directly with mqtt server?

    ReplyDelete
    Replies
    1. I think this should work, but I wouldn't recommend it if you need authentication on the mqtt broker, because the login credentials would be visible within the client side javascript.

      Delete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. do i have to configure the mqtt broker (I am using mosquitto on a raspberry pi3) .. I am able to load the page and toggle the buttons but no messages are being sent to the MQTT clients (mosquitto subscribers)? Great tutorial I ahve learned alot thus far..

    ReplyDelete
  9. Just reread my previous question about mosquitto config.. to be clear.. In my case the webpage does not react to MQTT messages being published or subscribed to?

    ReplyDelete
  10. Great! That's what I was looking for. But if I want to add more items, how should I subscribe to more topics as the same time? I'm new to mqtt

    ReplyDelete
  11. We do get similar error when we sometimes run our express app. We have to follow the same in that case. We need to check if its running in any terminal. If you want to find and kill process, follow these steps:


    ps aux | grep node
    Find the process ID (second from the left):
    kill -9 PRCOCESS_ID

    OR...
    Use a single command to close all the running node processes.

    ps aux | awk '/node/{print $2}' | xargs kill -9

    ReplyDelete
  12. This comment has been removed by a blog administrator.

    ReplyDelete