Fun with EWD.js and the Raspberry Pi

In this article I want to have some fun and explain how to create and set up two EWD.js applications, one running on a dEWDrop server and the other on a Raspberry Pi.  The fun part is that the application running on the Raspberry Pi will send messages to the application running on the dEWDrop server which will display them in a browser.  The dEWDrop server will then respond back to the Raspberry Pi with an acknowledgement.  The trick is that each machine uses the socket listener port that EWD.js makes available for external messaging.

Although this example is pretty simple and rudimentary, it will hopefully demonstrate the kind of powerful things you can do with EWD.js, and in particular some of the cool tasks you could give to the wonderfully cheap and cheerful, but highly capable  Raspberry Pi.

Basic Setup

So let’s start with the basics.  I have a Raspberry Pi on which I’ve installed EWD.js.  Read Appendix 4 in the EWD.js Reference Guide on how to do this.  On my network it’s been allocated an IP address of 192.168.1.113.  By default EWD.js sets up a socket listener connection on port 10000.

My “main” EWD.js server for the purposes of this experiment is a dEWDrop server, running as a virtual machine with Bridged Networking configured.  Appendix 2 in the EWD.js Reference Guide explains how to set up a dEWDrop VM and how to install and configure EWD.js on it.  On my network, my dEWDrop VM has been allocated an IP address of 192.168.1.101.  Once again, EWD.js sets up a socket listener connection on port 10000.  However, on a dEWDrop server we have to explicitly open this port in order to allow it to be accessed from outside.  To do this, open an SSH connection to the dEWDrop server, login and enter the following command:

  sudo ufw allow 10000/tcp

By the way, instead of a dEWDrop server we could use any system running EWD.js, including, of course, a second Raspberry Pi.

OK we’re now ready to start coding.

Raspberry Pi

Let’s start with the Raspberry Pi.  Create a new EWD.js application directory named pinject, eg:

  mkdir /home/pi/www/ewd/pinject

Now create a file named index.html in this directory containing the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>Pi Message Injector</title>
 </head>
 <body>
 <h2>Raspberry Pi Message Injector Application</h2> 
 <input id="message" type="text" />
 <input type="button" value="Send Message" onClick="injectMessage(document.getElementById('message').value)" />

 <script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
 <script src="/socket.io/socket.io.js"></script>
 <script src="/ewdLite/EWD.js"></script>
 <script>
 EWD.application = {
   name: 'pinject'
 };
 EWD.sockets.log = true;

 var injectMessage = function(message) {
   EWD.sockets.sendMessage({
     type: 'injectMsg',
     params: {
       value: message
     }
   });
 };
 </script>
 <!--[if (IE 6)|(IE 7)|(IE 8)]>
 <script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">
 </script>
 <![endif]-->
 </body>
</html>

Next, in the/home/pi/node/node_modules directory, create our application’s back-end module file which must be named pinject.js (ie matching the EWD.application.name value we defined in the index.html file above).  This should contain the following:

var net = require('net');
module.exports = {
  onMessage: {
    injectMsg: function(params, ewd) {
      var client = net.createConnection({
          host: '192.168.1.101',
          port: 10000
        },
        function() {
          var messageObj = {
            "recipients": "byApplication",
            "application": "pilistener",
            "password": "keepThisSecret!",
            "type": "msgFromPi",
            "message": params.value
          };
          var message = JSON.stringify(messageObj);
          client.write(message);
          client.destroy();
        }
      );
    }
  }
};

So let’s quickly take a look at what this application will do.

The index.html page describes what will appear in the browser when you run the application.  It will provide a simple input box and button.  When you enter some text into the input box and click the button, it will send a web-socket message (with a type of “injectMsg”) to the back-end module (pinject.js).  The back-end module is nothing more than a handler for messages with a type of injectMsg: whenever such a message is received, it opens up a socket connection to port 10000 on the EWD.js system running on IP address 192.168.1.101 – ie the dEWDrop server.  It then writes a message into that port and promptly closes the connection.  In order for the message to be handled by the dEWDrop server, the message has to include the password of the EWD.js master process that is running on the dEWDrop server.  For the purposes of this example I’m just using the default password of keepThisSecret!.  The message will be delivered to all users of an application named pilistener.

You can fire up the application on the Raspberry Pi if you want.  Make sure you have the EWD.js master Node.js process up and running.  Then just bring up a browser and enter the URL:

https://192.168.1.113:8080/ewd/pinject/index.html

Don’t try clicking the button yet – we need to get the listening application up and running on the dEWDrop server.  However, if you bring up Chrome Developer Tools console, you should see that the application has properly registered itself:

onMessage: {"type":"EWD.connected"}    EWD.js:181
Registered successfully                EWD.js:184

dEWDrop Server

So now we’ll turn out attention to the dEWDrop server.

First create a new EWD.js application directory named pilistener:

  mkdir /home/vista/www/ewd/pilistener

Now create a file named index.html in this new directory containing the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>Pi Listener</title>
 </head>
 <body>
 <h2>Raspberry Pi Listener Application</h2> 

<h3>Messages sent from Raspberry Pi</h3>
<div id='messages'>
</div>

 <script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
 <script src="/socket.io/socket.io.js"></script>
 <script src="/ewdLite/EWD.js"></script>
 <script>
 EWD.application = {
   name: 'pilistener'
 };
 EWD.sockets.log = true;

 EWD.onSocketMessage = function(messageObj) {
   if (messageObj.type === 'msgFromPi') {
     var div = document.createElement('div');
     var text = document.createTextNode(messageObj.message);
     text = div.appendChild(text);
     document.getElementById('messages').appendChild(div);
   }
 };

 </script>
 <!--[if (IE 6)|(IE 7)|(IE 8)]>
 <script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">
 </script>
 <![endif]-->
 </body>
</html>

Now fire up this page in a browser (first making sure that the EWD.js master Node.js process is up and running):

   https://192.168.1.101:8080/ewd/pilistener/index.html

Bring up the Chrome Developer Tools console and you should see that this application has also registered itself.

Try it out!

OK we’re now ready for the fun to start.  Refresh the page that’s running on the Raspberry Pi, enter some text into the input box and click the button.  With a bit of luck you should see the message appearing in the browser page that’s running on the dEWDrop server:

Raspberry Pi:

Screen Shot 2013-11-22 at 17.18.01

dEWDrop VM:

Screen Shot 2013-11-22 at 17.18.42

Processing Incoming Messages 

So that’s pretty interesting – but we can do more with the messages that are received on the dEWDrop server.  For example, we can add a browser-side handler that listens for these incoming messages and sends them to the back-end where they can be processed.  Let’s add one.  Just edit the index.html file on the dEWDrop server as follows – we’re just adding the code within the asterisks:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>Pi Listener</title>
 </head>
 <body>
 <h2>Raspberry Pi Listener Application</h2> 

<h3>Messages sent from Raspberry Pi</h3>
<div id='messages'>
</div>

 <script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
 <script src="/socket.io/socket.io.js"></script>
 <script src="/ewdLite/EWD.js"></script>
 <script>
 EWD.application = {
   name: 'pilistener'
 };
 EWD.sockets.log = true;

 EWD.onSocketMessage = function(messageObj) {
   if (messageObj.type === 'msgFromPi') {
     var div = document.createElement('div');
     var text = document.createTextNode(messageObj.message);
     text = div.appendChild(text);
     document.getElementById('messages').appendChild(div);
    //******************************
     EWD.sockets.sendMessage({
       type: 'messageFromPi',
       params: {
         message: messageObj.message
       }
     });
     //******************************
   }
 };

 </script>
 <!--[if (IE 6)|(IE 7)|(IE 8)]>
 <script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">
 </script>
 <![endif]-->
 </body>
</html>

So now we need a back-end module to process these messages. In the directory /home/vista/www/node/node_modules create a file named pilistener.js containing the following:

var net = require('net');
module.exports = {
  onMessage: {   
    messageFromPi: function(params, ewd) {
      var client = net.createConnection({
          host: '192.168.1.113',
          port: 10000
        },
        function() {
          var messageObj = {
            "recipients": "byApplication",
            "application": "pinject",
            "password": "keepThisSecret!",
            "type": "msgToPi",
            "message": "From 192.168.1.113: I got your message: " + params.message
          };
          var message = JSON.stringify(messageObj);
          client.write(message);
          client.destroy();
        }
      );
    }
  }
};

Let’s examine what this will be doing – it’s just a handler for incoming messages of type ‘messageFromPi’ which is the type we assigned to the copy of the message that we received from the Raspberry Pi and that we’re sending back from the browser. You could do anything you like now with the message – eg store it in the database or use it as a trigger to do some more complex processing.

However, what I’m going to demonstrate is how you can send an acknowledgement message back to the Raspberry Pi. It’s pretty simple and just the same kind of logic we used on the Raspberry Pi itself: it’s opening up port 10000 on the Raspberry Pi and injecting a message back into the EWD.js service that’s running on it. We need to supply the password, of course, which, once again, is the password assigned to the EWD.js service running on the Raspberry Pi: I’m just using the standard default value.

You could run this now and you should see the returned message appearing in the Chrome Developer Tools console for the browser running the Raspberry Pi application. However, to make it clearer, let’s modify the index.html file on the Raspberry Pi to display the returned messages. Once again we’re just adding the extra JavaScript code and HTML that’s shown below within the asterisks:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>Pi Message Injector</title>
 </head>
 <body>
 <h2>Raspberry Pi Message Injector Application</h2> 
 <input id="message" type="text" />
 <input type="button" value="Send Message" onClick="injectMessage(document.getElementById('message').value)" />
 <!-- ************************* -->
 <h3>Incoming messages</h3>
 <div id="messages"></div>
 <!-- ************************* --> 
 <script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
 <script src="/socket.io/socket.io.js"></script>
 <script src="/ewdLite/EWD.js"></script>
 <script>
 EWD.application = {
   name: 'pinject'
 };
 EWD.sockets.log = true;

 var injectMessage = function(message) {
   EWD.sockets.sendMessage({
     type: 'injectMsg',
     params: {
       value: message
     }
   });
 };
//**********************************************
 EWD.onSocketMessage = function(messageObj) {
   if (messageObj.type === 'msgToPi') {
     var div = document.createElement('div');
     var text = document.createTextNode(messageObj.message);
     text = div.appendChild(text);
     document.getElementById('messages').appendChild(div);
   }
 };
//************************************************
 </script>
 <!--[if (IE 6)|(IE 7)|(IE 8)]>
 <script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">
 </script>
 <![endif]-->
</body> 
</html>

Try it out again!

Reload the index.html pages for both machines and now send a message from the Raspberry Pi.  You should not only see the message arrive on the dEWDrop application, you should now also get an acknowledgement returned to the Raspberry Pi:

Raspberry Pi:

Screen Shot 2013-11-22 at 18.15.22

dEWDrop VM:

Screen Shot 2013-11-22 at 17.52.06

Start Hacking!

I hope you can start to see how powerful this external message injection mechanism can be, and I also hope you’re now beginning to imagine all kinds of ways you could put it to use.

I’m also hoping that you’re now imagining all kinds of possible uses for the $35 Raspberry Pi.  It really is a most extraordinary device!

Have fun!

Advertisements

One comment

  1. Of course you don’t have to use a Raspberry Pi for this technique – any EWD.js system running on any platform can communicate with any other EWD.js system via the built-in socket listener.

    Conversely, you could get multiple Raspberry Pis inter-communicating this way.

    Note: it’s probably a good idea to limit this technique to EWD.js systems within a network and behind a firewall to the outside world. Although the connection is protected – the connecting system needs to know the EWD.js password of the system it’s connecting to – all communication is in the clear.

    If you want to perform similar inter-communication safely across the Internet, you can use the secured web service interface provided by each EWD.js system – that way you can properly encrypt the communication over SSL and you have the added security provided by the digitally-signed HTTP requests that EWD.js requires. On the down-side, all that security and the HTTP protocol makes it a more expensive way to communicate than the very lightweight socket listener.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: