© Indira Knight 2018
Indira KnightConnecting Arduino to the Webhttps://doi.org/10.1007/978-1-4842-3480-8_2

2. Creating a Web Server

Indira Knight1 
(1)
London, UK
 

To get started on the web side of connecting Arduino to the Web, it is useful to have a basic understanding of web technologies. This chapter will go through some of the principles, including what a web server is, how a URL is constructed, what routes are, and what Node.js is. It will then get practical, and you will learn how to create a web server with Node.js and send data back and forth from the server to a web page. It will cover Node.js, ejs, and socket.io.

What Is a Web Server?

A web server serves pages to web browsers; it also processes information and stores data and assets for the pages. It allows requests to be processed using Hypertext Transfer Protocol (HTTP). This protocol allows networks to communicate with each other using addresses called Uniform Resource Locators (URLs), the address to your web page. URLs have a defined structure starting with the protocol, followed by the domain name, the domain extension, and an optional file and folder names; see Figure 2-1.
../images/453258_1_En_2_Chapter/453258_1_En_2_Fig1_HTML.jpg
Figure 2-1

URL structure

A domain name is a translation into natural English of an Internet protocol (IP) address. An IP address is a series of numbers and anything that connects to the Internet has one. This includes smartphones and smart TV’s; any piece of equipment connected to the Internet will have an IP address.

When computers on the Internet talk to each other they use their IP address. When you type a web address into your browser it is converted into an IP address. This tells the web server the address of the page you want. It is the route to that page. If the server finds the page it will return it back to your browser. If it can’t, it will return an error page.

Web servers have a number of conventions to connect and transfer data from one computer on the network to another. One of these is representational state transfer, which is known as RESTful. It makes computer systems interoperable; this means however a server is set up, if it implements the RESTful web services it can talk to any other server that also implements them. When HTTP uses RESTful the requests GET, POST, PUT, and DELETE can be used. For example, POST allows you to fill in a form on a web page and post it to the browser.

You can create a web server on your own computer, and using Node.js is one way to do this. This means you can develop applications on your local machine and test them before deploying them. The local web server uses the domain name localhost, and this resolves to an IP address 127.0.0.1.

Routing

Without routes you would not be able to see web pages. Routing determines how a web server responds to a URL request from the web browser. Going back to example.com, the server has to know what page to serve when someone types in that URL. If you add on other pages such as example.com/about there will have to be a route in the server for this page as well. A route also tells the server how it should respond to a request. It does this using RESTful commands; if a route starts with GET the server knows it needs to get content for a page. If it starts with POST, the server knows it will be receiving data from a web page and the route will define what should be done next.

What Is Node.js?

Node.js is a runtime environment for executing JavaScript server code. It means you can use the same language, JavaScript, on the browser and on the server. Using Node.js you can create routes to web pages, connect to localhost, connect to a database, and send data to web pages with JavaScript. It allows you to build web applications using the same language throughout.

Node.js works really well with Arduinos. Using the serial port you can use the server to pass data from an Arduino to a web page and pass Data from the web to an Arduino.

Apart from downloading Node.js you will need to download other packages that make it simpler to create the application you want. You do this with a package manager; there are a few different ones, but node package manager (npm) is used in this book.

Using a Command-Line Interface

A command-line interface is a way of sending instructions to your computer using text. You can use it for many things including moving around your computer’s directories and to create new files and running code.

To work with Node.js you need to use a command-line interface. You use it to install new modules, start the server, and see messages and errors from the application.

Windows and Mac come with inbuilt command-line interface applications. In Windows it is called a command prompt or cmd.exe, and on a Mac it is called a terminal. Both will open a console window for the typing in of commands.

It is a very powerful tool and needs to be used with caution as you can wipe your system or make changes that are hard to undo.

The command-line interface is implemented in what is called a command-line shell. The shell is a program that accepts text commands and translates them into a language the operating system will understand.

When you open a console window, it should be displaying the home directory for the logged-in user. This is the top directory for that user and from it you can navigate to the files and folders of that user.

Using The Mac Terminal

The Mac terminal application is located inside the utilities folder that is inside the application’s folder. The path to it is the following:

Hard drive/Applications/Utilities/Terminal

When the application is open you should see a console window showing your home directory followed by $: for example:~ <username>$

Try out the following commands and review Table 2-1 for some additional ones you may find useful:
  1. 1.

    Open the terminal, and a new console window will open.

     
  2. 2.

    Type ls + return and you will see a list of all the files and folders at the current directory.

     
  3. 3.

    Type cd <folder name> + return and you will move into that directory.

     
  4. 4.

    Use ls to list files and directories then type cd and the directory name to move into another directory.

     
  5. 5.

    Type cd .. + return, and you will move up one folder in the directory.

     
  6. 6.

    Type cd + return, and you will move to your home directory.

     
  7. 7.

    Type Ctrl + l or Cmd+k, and both of these will clear the console screen. Crtl+l just clears the screen, and Cmd+k also clears the terminal buffer.

     
Table 2-1

Some useful terminal Commands

Command

Result

pwd

Writes the full path of the current directory

ls

Lists the content of a directory

cd <directory name>

Path to directory 1 level below

cd <directory name>/<directory name>

Path to directory 2 levels below

cd ..

Move up a directory

cd

Moves back to the home directory

mkdir <directory name>

Will make a new directory in the current directory

touch <file name.extension>

Will create a new file with that name and extension

Using The Windows Command Prompt

The windows console is called the command prompt or cmd.exe. There are a number of ways to open a command prompt console window, and these will change depending on which version of windows you are running (see Table 2-2). You can use Windows search to find the command prompt; the search is Cortana on Windows 10. Start to type in “command prompt” in the search field; the best match should be the desktop app “Command Prompt.” Click on “Command Prompt” to open a console window.

When the application is open you should see a console window showing your home directory followed by a > It should look like this: C:UsersUsername>, and you start typing after the >.

Try out a few commands:
  1. 1.

    Open the command prompt, and a new console window will open.

     
  2. 2.

    Type dir + enter, and you should see all the files and folders in the current directory.

     
  3. 3.

    Type cd <folder name> + enter, and you will move into that folder.

     
  4. 4.

    Use ls to list files and directories and cd to move into another directory.

     
  5. 5.

    Type cd .. + enter, and you will move up one folder in the directory.

     
  6. 6.

    Type cd %userprofile% + enter to return to the home directory.

     
  7. 7.

    Type cls + enter, and the console screen will be cleared.

     
You can have optional arguments in a command. If you use the dir command you will see a lot of information about each file or folder in the directory. If you just wanted to see the names you would type dir /b.
Table 2-2

Some useful command prompt commands

Command

Result

echo %cd%

Writes the full path of the current directory dir

cd <directory name>

path to directory 1 level below the current directory

cd <directory name>/<directory name>

Path to directory 2 levels below the current directory

cd ..

Move up a directory

cd

Moves back to the home directory

mkdir <directory name>

Will make a new directory in the current directory

NUL> <filename.extension>

Will create a new file with that name and extension

Note If you start writing a directory name in the console window and then press the tab key, the rest of the directory name will be filled in for you, as long as it is the only directory with those letters.

To move back and forward to previous commands, use the up and down arrows on the keyboard.

The Mac console is case sensitive. The Mac console is white space sensitive.

Setting Up a Node.js server

Now that the background has been covered, it’s time to start coding. If you don’t have Node.js installed on your computer, you will need to install it along with the node package manager. Depending on what you already have installed on your computer, it might take some time, but once it’s done, further downloads are a lot quicker.

Installing Node.js

First, if you are not sure if you have Node.js installed on your computer, you can check in a console window.

Check If Node.js Is Installed

  1. 1.

    Open a console window.

     
  2. 2.

    At the console prompt type node -v if Node.js is installed you should see your version number (e.g., v6.10.3).

     
  3. 3.

    At the console prompt type npm -v and if npm is installed you should see the version number (e.g., 3.10.10),

     

If you see version numbers skip the next step on installing Node.js and go straight to the “Creating an Application” section.

Install Node.js On Windows

In Windows you can install Node.js straight from the Node.js website.
  1. 1.
     
  2. 2.

    Download the version for Windows(x64). For this book I downloaded v6.10.3.LTS (.msi).

     
  3. 3.
    Run the installer; to do this:
    1. a.

      Double-click on the downloaded file; it should be in your downloads folder with a name similar to node-v6.10.3.x64.

       
    2. b.

      The installer window should appear’ press the run button, and this opens the Node.js Setup Wizard, then press the next button.

       
    3. c.

      The license agreement will appear, and you need to agree to the license to install Node.js. If you agree, check the check box and press the next button.

       
    4. d.

      You can accept the default settings by pressing the next button until you see the finish button, and the default setting will install Node.js to a default directory.

       
    5. e.

      Press the finish button to complete the installation.

       
     
  4. 4.

    At the prompt, let the app make changes to your device.

     
  5. 5.

    Restart your computer.

     
  6. 6.

    Check that Node.js and npm have been installed by following the instructions in the “Check if node.js Is Installed” section above.

     

Install Node.js On a Mac

On a Mac there are a number of ways to install Node.js. The easiest way is to download the application from the Node.js website. While this is the simplest way it does have a disadvantage. It installs Node.js in a way that means you may need admin privileges to install supplemental modules and libraries. You can install these modules and libraries using the sudo command before the install command. The sudo command gives you admin privileges for that installation. sudo stands for Super-User DO and is used with UNIX-style operating systems. This allows you to install the package as an admin user.

Using sudo is not considered best practice as having admin rights means you can make unwanted changes to your computer. Using sudo can also affect how some of the modules work.

Another way to install Node.js is to use a Node version manager(NVM) ; it installs it so you don’t need admin privileges to install other modules and libraries. It is slightly harder to install as you need Xcode installed and you will need a .bashprofile file. There is another advantage: you can easily change between different versions of Node.js.

Installing Node.js from the Node.js Website

If you install Node.js this way you may get errors when you install new modules for your application and they won’t download. If this happens you will need to install the module again with admin privileges. To do this you type sudo before the install command. You will then be prompted to write your password.
  1. 1.
     
  2. 2.

    Download the version for macOS(x64); for this book I downloaded v6.10.3.LTS (.pkg).

     
  3. 3.

    Run the installer and follow through its requests, and let it install at the default directory.

     
  4. 4.

    Let the app make changes to your device.

     
  5. 5.

    Restart your computer.

     
  6. 6.

    Check that Node.js and npm have been installed.

     

Installing Node.js Using a Node Version Manager(NVM)

To install with an NVM you need to have Xcode installed on your Mac and a .bashprofile.

If you don’t have Xcode installed, install it from the app store; this can take a couple of hours.
  1. 1.

    Open a terminal window, and make sure you are at the root ~ <name>$ if not at the prompt type cd.

     
  2. 2.

    Check you have a .bashprofile file. At the $ prompt, type open -a TextEdit.app .bash_profile and if you have a .bashprofile it will open, or you can close the file.

     
  3. 3.

    If you don’t have a .bash_profile at the prompt type touch .bash_profile.

     
  4. 4.

    To install the NVM at the console prompt type:

    curl https://raw.githubusercontent.com/creationix/nvm/v0.25.0/install.sh | bash.

     
  5. 5.

    To install the latest stable version of Node.js at the prompt type nvm install stable.

     
  6. 6.

    At the prompt type nvm use node.

     
  7. 7.

    Install the version on Node.js used in this book at the prompt type nvm install 6.11.0.

     
  8. 8.

    Make version 6.11.0 the default version when you open a console window. At the prompt type nvm alias default 6.11.0.

     
  9. 9.

    Start using this version of Node.js and at the prompt type nvm use 6.11.0.

     
  10. 10.

    You can see the versions of Node.js you have installed: type nvm ls.

     
  11. 11.

    Check that Node.js and npm have been installed.

     

You can find more information about nvm and how to use it on the github page https://​github.​com/​creationix/​nvm.

Create a Node.js Application

By the end of this chapter you will have built a small application that uses socket.io to send out updates from the server to connected browsers. You will build up to this by going through a number of steps including creating a web server, creating a route to a web page, some basic styling of a web page, and sending data from the server to the browser. You will send data from the server in two different ways: first through the route function to the web page and then by using a web socket.

To write and edit the code you will need a specialized text editor. This can be a source code editor or an integrated development environment (IDE). They are easy to download and install. There are a number available such as Sublime Text, Atom, and Visual Studio code.

The first thing you need to do is create the directory for the application. I called mine chapter_02, so this will be the name of the application.

Create The Application Directory

  1. 1.

    Open a console window.

     
  2. 2.

    Move to the directory you want to store the project, in terminal type cd <path>/<to>/<directory>.

     
  3. 3.

    Create a new folder for the project, in terminal type mkdir <directory name>.

     
  4. 4.

    Move into the new directory, in terminal type cd <new directory name>.

     

The Directory Structure

When you create a web application you will need a directory structure. The main folder for your application will be the root of the application. All other files and folders relating to the application should be in this folder. The files that make up your application will refer to files and folders in this structure. You will create some of these files and folders, and others are created automatically during the initial setup or when you download modules.

Figure 2-2 shows the directory structure for this chapter. The package.json file will be created on setup and the node modules folder will be created automatically when you download new modules. The “/” character represents the root of the application.
../images/453258_1_En_2_Chapter/453258_1_En_2_Fig2_HTML.jpg
Figure 2-2

The directory structure for the application

Using NPM Init To Create An Application

npm stands for node package manager. It hosts hundreds of thousands of packages of reusable code that you can download and use in projects.

npm also has a command called npm init, a useful way to create a Node.js application. It will ask a series of questions and then create a package.json file. You can press Ctrl+C to quit the process at any time.

It is easy to create the skeleton of the Node.js server using npm:
  1. 1.

    Open a console window.

     
  2. 2.

    Navigate to the folder you will use for your application.

     
  3. 3.

    At the console prompt type npm init+enter.

     
  4. 4.

    Change the default answers or press enter to accept them. Keep the default entry point as index.js.

     
  5. 5.

    Open up the project folder in a code editor. Open the root folder for the application, as you want to be able to see all the files and folders connected to the project. At the moment there you should see one file package.json.

     

Figure 2-3 shows an example of a package.json file.

package.json is an important file, it holds the metadata for the application and is used to handle the application’s dependencies. As you start to install libraries there will be a reference to them in the package.json file. If you share your application files you wouldn’t include all the libraries files. As the package.json has a reference to them, you can use npm install to install them at the copied location.
../images/453258_1_En_2_Chapter/453258_1_En_2_Fig3_HTML.jpg
Figure 2-3

An example of a package.json file

Note The name has to be in lowercase letters without spaces though you can use underscores and dashes.

Create A Node.js Server

In Node.js you create a JavaScript file that will start the server. It is stored in the root of the project and will be the entry point for the application. This file is often called app.js or index.js. When I used npm init to create the package.json, I kept the default for the entry script of index.js so now the index.js file needs to be created.

Create a new file at the root of your application called index.js. This can be created in your text editor or using the console. Make sure you are in the applications directory at the same level as package.json.

In the newly created index.js file write in the following code from Listing 2-1.

var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});
Listing 2-1

index.js code

Listing 2-1 shows the basic code for setting up a web server using Express.js. Express.js is not part of the Node.js library so it will have to be installed in a minute, but first I will explain the code in Table 2-3.

The Code Explained

Modules, such as Express.js, needed for the server are loaded at the top of the page and assigned to variables. JavaScript uses the var keyword to create a variable.
Table 2-3

index.js code explained

var http = require('http');

This line brings in the HTTP interfaces to the application; this allows the server to communicate with the browser via the HTTP protocol.

var express = require('express');

This includes the express framework that we will be using to create the server and the routes. Express comes with a number of functions that make it easier to set up a node server. It is not part of the Node.js library and so it needs to be installed.

var app = express();

The express application is called and the return value is placed in a variable. This holds a new express application.

var server = http.createServer(app);

This creates a server object that is called when a server request is made.

server.listen(3000, function() {

});

This tells the server to listen for requests to the server on the port 3000.

console.log('Listening on port 3000...');

console.log is a JavaScript function that will output messages to the console. It is used here to tell you that the server is running.

Using NPM To Install Libraries

At the moment if you ran this code, there would be an error. It is using an external library called Express.js, which is not part of Node.js. Express.js makes it a lot easier to create a web server. It needs to be downloaded and a reference to it saved in the package.json. This can be done using npm:
  1. 1.

    Open a console window and make sure you are in the same directory as the package.json file.

     
  2. 2.

    At the command line type npm install [email protected] --save + enter.

     
  3. 3.

    Once it’s downloaded start the server. In the console make sure you are at the root of the application, the same level as index.js. At the prompt type node index.js.

     

If you get an error installing Express.js and are on a Mac it may be that you need admin rights to install it. Try installing again, this time type sudo npm install [email protected] --save then type in the computer’s password at the password prompt.

In the console you should now see the console log Listening on port 3000.

If you are using Windows you may see a security alert that Windows firewall has blocked some features of this app. Tick the box that says: Private networks, such as my home or work network.

If you open a web browser and type in localhost:3000 you should see: Cannot GET /

That is because there isn’t a route yet so the server does not know what page to serve to the browser. You will be creating routes in a minute.

If you look at your applications directory you will see there is a new folder called node modules. This is created the first time you install a new library into your application. If you look inside you will see that the files and folders for Express.js are in it.

Note You use--save to save a reference to the downloaded module in the package.json file.

In this book I will use @ to install new modules. This means you will install the same version I have been using. Without the @ it will install the latest module.

Creating a Route To a Web Page

To create a simple route that sends some text to a web page, using the code in Listing 2-1, add into your file the following commands in bold, which are described further in Table 2-4:

var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
app.get('/', function (req, res) {
  res.send("Hi There!");
});
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});

The Code Explained

Now if you restart the server you should see the text Hi There on the web page.
  1. 1.

    Type Ctlr+c to stop the server.

     
  2. 2.

    In the terminal type node index.js again to restart the server.

     
  3. 3.

    Refresh the web browser.

     
Table 2-4

index.js code explained

app.get('/', function (req, res) {

res.send('Hi There!');

});

The function app.get creates a route to the root of the application. '/' represents the root which would be the main URL or in this case localhost:3000. If you wanted to send the message to a different web page, for example, to an about page you would use app.get('/about', function (req, res).

Add a second app.get below the first app.get to the code in Listing 2-1.

app.get('/about', function (req, res) {
  res.send("this is an about page");
});
Now you need to restart the server so it picks up the new route:
  1. 1.

    Press Ctlr+c to stop the server.

     
  2. 2.

    In terminal type node index.js again to restart the server.

     
  3. 3.

    Refresh the web browser and go to localhost:3000/about.

     

You should now see the words this is an about page on the web page. You can delete the about route.

NodeMon

Every time you make a change to the server you have to stop and restart the server for the change to be picked up. There is a useful library called nodemon that will notice when you make a change to a file that it is watching and restarts the server for you. It is easy to install using it in a console window. It should be installed globally so it is accessible to all your Node.js applications.

Installing Nodemon

  1. 1.

    Open a console window and make sure you are at the home directory; you can go to the home directory on a Mac by typing cd and on a Windows pc by typing cd %userprofile%

     
  2. 2.

    At the prompt type npm install nodemon -g (-g installs it globally).

     
  3. 3.

    In the console navigate to the root of the chapter_02 application, do this with the cd command, for example cd Documents/code/chapter_02

     
  4. 4.

    When you are at the root of your Node.js application in the console, start the server by typing nodemon and press the enter key.

     

Now if you make a change in the index.js file you can refresh the browser and see the update. Nodemon automatically starts the main JavaScript file listed in package.json.

You don’t need to save this to the package.json as it is not part of your application; it is a helper when developing the application.

Creating a Web Page

So far you have sent data to a web browser but it is just printing out a message from the router. Now you need to create a web page. Normally web pages are created in files with an .html extension. These are static web pages. As you will be updating the page with data from the server, you need to create a dynamic page that can take this data.

One way to do this is for the .html page to make AJAX requests to the server, which in turn returns some data. This relies on the browser page making a request for data from the server.

Another approach, which is more efficient, is to let the server update a web page with the data it has. In Node.js this is done with template engines.

Template Engine

A template engine allows you to create variables throughout a web page that the server can update without the web page making a request. Later in the book we will be passing data from an Arduino to the server. As the web page will be created with a template engine, the page will be updated automatically with the new data.

There are a number of different template engines you can use, some of which I have listed in Appendix B. This book uses ejs, embedded JavaScript.

Set Up The Server

Some code needs to be added to the index.js file to use ejs but first ejs has to be added to the project:
  1. 1.

    Either open a console window and navigate to the root of the application directory, or navigate to the root of the application directory; or if the server is running at the root of the application press Ctlr + c to stop it.

     
  2. 2.

    At the console prompt at the root of the application type npm install [email protected] --save + enter.

     

You should now be able to see ejs in your package.json file. It is just one line of code to include ejs in the project. Update your index.js file from code (Listing 2-1) with the line of code in bold:

var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
app.set('view engine', 'ejs');
app.get('/', function (req, res) {
  res.send('Hi There!')
});
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});

This new line of code will allow you to use ejs in the project.

Up to now in the route you have used res.send. Using res.send in a route allows you to send simple data to a web page, but for most applications you would want to be able to send pages that can hold a lot more information. To do this you use the function res.render; this allows you to specify a file that will render in the browser and also send it new data.

Change your index.js file from code (Listing 2-1) with the code in bold; this adds a couple of variables and changes the route so it uses res.render instead of res.send:

....
app.set('view engine', 'ejs');
var title = "Some Arduino components starting with p"
var componentArray = ['potentiometer', 'piezo', 'phototransistor', 'pushbutton'];
app.get('/', function (req, res) {
    res.render('index', {
                title: title,
                components: componentArray
    });
});
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});

The Code Explained

The new code starts with two variables that hold the data to be passed to the browser (see Table 2-5).
Table 2-5

index.js code explained

var title = "Some Arduino components starting with p"

The title variable holds some text. In JavaScript strings are surrounded by either “ ” or ‘ ‘.

var componentArray = ['potentiometer', 'piezo', 'phototransistor', 'pushbutton'];

In JavaScript, [ ] is used to create an array. An array is a collection of data that can be accessed by its index (position) within the array. componentArray is an array of four elements that are all strings. The index in a JavaScript array starts at 0. To access the first element of the array you would use componentArray[0], which would return the string potentiometer. componentArray[3] would return the string pushbutton.

res.render('index', {

      title: title,

      components: componentArray

});

Now instead of rendering a string you are telling Node.js which page you would like to render. In this case it is the index.js file. You then list the data you want passed to the page, in this case the title and the componentArray.

  1. 1.

    Start the server at the application route. Make sure you are in the same folder as the index.js file. At the console prompt type nodemon.

     
  2. 2.

    Refresh your web page, and you should see an error.

     

You should see an error on the page and in the console window that looks something like this:

Error: Failed to lookup view “index” in views directory “/Users/indie/Documents/web/book/chapter 2/03_set-up-ejs/views”

This is because now you are asking it to find an index page that doesn’t exist.

Set Up The Web Page

An ejs page looks similar to an html page except it uses .ejs suffix rather then .html. You can pass ejs page data from the server as a variable. On the page you still use the same html tags but you can also use ejs syntax. Pages created with ejs need to be put in a folder called views.
  1. 1.

    At the root of the application create a new folder called views.

     
  2. 2.
    Create a new file called index.ejs inside the views folder. To do this in a console window:
    1. a.

      at the root of the application type cd views

       
    2. b.

      on a Mac type $ touch index.ejs

       
    3. c.

      on a Windows pc type NUL> index.ejs

       
     

In Windows you might get a console response of Access is denied but the file should have been created.

In the newly created index.ejs file write in the code from Listing 2-2.

<!DOCTYPE html>
<html>
<head>
    <title>an ejs page</title>
</head>
<body>
    <h1>EJS</h1>
    <p>This page is an ejs page and will show data from the server</p>
</body>
</html>
Listing 2-2

index.ejs code

In a console window, make sure you are at the root of the project and restart the server. On the browser go to http://localhost:3000/ and there should no longer be an error. You should now see the text on the web page . You created this page with some simple HTML. HTML, which stands for HyperText Markup Language, is the common markup language used to create web pages. I will go into more detail about HTML in Chapter 4. It sets out the structure of the page and the elements within it.

Adding Data To The Web Page

The server has passed to the browser the data from res.render. It has passed a string called title that contains the text "Some Arduino components starting with P" and an array called components that contains ['potentiometer', 'piezo', 'phototransistor', 'pushbutton']. Using ejs the browser now has access to this data.

Update the index.ejs from Listing 2-2 with the text in bold:

<!DOCTYPE html>
<head>
    <title>an ejs page</title>
</head>
<body>
    <h1>EJS</h1>
    <p>This page is an ejs page and will show data from the server</p>
    <h2><%= title %></h2>
    <% components.forEach(function(component) { %>
        <p>component: <%= component %> </p>
    <% }); %>
</body>
</html>

The Code Explained

<% %>, or <%=  %> are part of the ejs library.

The <% %> tags are used when you are writing JavaScript, it will run the JavaScript inside the tags, and the text won’t appear on the page. Usually when you want to add JavaScript to a web page you have to wrap it in script tags <script></script> that you will be using later. EJS has its own version of the script tag, <% %>, which you use when writing code that accesses the data passed from the server.

When the <%= %> tags are used, then content inside them is seen on the page. Inside the tags you can reference the variable from the server that was passed to the browser and see it on the web page. See Table 2-6.
Table 2-6

index.ejs code explained

<h2><%= title %></h2>

The title is part of the data passed from the server. As you want to see the title you use <%= %>. You can wrap the EJS in any HTML tags you like. In this case the ejs is wrapped in a H2 tag.

<% components.forEach(function(component) { %>

<p>component: <%= component %> </p>

<% }); %>

This uses a JavaScript forEach function to iterate over the array data passed from the server and writes out each element of the array.

Adding CSS

CSS stands for Cascading Style Sheet, and it is used to style elements on a web page. A web page without CSS looks very basic. While CSS can be added in the .ejs page it is best practice to create a separate .CSS file to hold the styles. You then need a link to the .css file in the .ejs page.

In a web application there are files called static files that are not created by the server and are used on the web page. These include CSS files, images, and JavaScript files. To use them in a .ejs file you need to know the path from the static file to the .ejs file. Express.js has a middleware function called express.static to help with this. You create a folder at the root of your application that will hold all your static files; this folder is normally called public. In the index.js file the express.static function is used to register the public folder. This means that the .ejs recognizes this folder as the root folder for your static files and you don't have to write the absolute path the to the .css file when you are calling it. You will write something like this: <link href="/css/main.css" rel="stylesheet" type="text/css">

To add CSS to the page first create a static folder.
  1. 1.

    At the root of the application create a new folder called public.

     
  2. 2.

    Inside this folder create another folder called css.

     
  3. 3.

    Inside the css folder create a file called main.css.

     
  4. 4.

    Update the index.js file to include the static function, with the updated code below.

     

Now update the index.js file from Listing 2-1 with the code in bold:

...
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
var title = "Some Arduino components starting with P"
var componentArray = ['potentiometer', 'piezo', 'phototransistor', 'pushbutton'];
...
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});

The Code Explained

There is one line of code needed to register the static files folder (Table 2-7).
Table 2-7

index.js code explained

app.use(express.static(__dirname + '/public'));

This tells the app that all the static files will be served from a folder called public.

Now open the main.css file you just created and add in the CSS (Listing 2-3):

*{
    margin: 0;
    padding:0;
}
body{
    background-color: #F2F3F4;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}
h1, h2, p{
    padding: 10px;
}
h1{
    background-color: #4ABCAC;
    color: white;
}
#components{
    margin: 10px;
    border: #F78733 solid 2px;
    display: inline-block;
}
Listing 2-3

main.css

You will also need to update the index.ejs file to tell it where to find the CSS file. Update the index.ejs file (Listing 2-2) with the HTML in bold:

<!DOCTYPE html>
<head>
    <title>an ejs page</title>
    <link href="/css/main.css" rel="stylesheet" type="text/css">
</head>
<body>
    <h1>EJS</h1>
    <p>This page is an ejs page and will show data from the server</p>
    <h2><%= title %></h2>
    <div id="components">
        <% components.forEach(function(component) { %>
            <p>component: <%= component %> </p>
        <% }); %>
    </div>
</body>
</html>

So with the server running, refresh your web page, and you should now see the new style; it is using the HTML tags and an id to style the content.

package.json and Version Control

Now that you have installed a few packages for your application it’s a good time to have another look at the package.json file. It holds information about the application including the names of the dependencies (modules) you installed followed by their version number.

These dependencies are written by different people and are updated at different times. These updates can break your code. Semantic versioning is used to track the changes. This means that each number of a version number has a particular meaning. The version number, as seen in Figure 2-4, is made up of three numbers separated with a full stop. The numbers increase with each new version and each number represents a different kind of update.
../images/453258_1_En_2_Chapter/453258_1_En_2_Fig4_HTML.jpg
Figure 2-4

Version control numbers

In the package.json file you can see the dependencies.

{
  "name": "set-up-routes",
  "version": "1.0.0",
  "description": "setting up simple routes",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "Indira",
  "license": "ISC",
  "dependencies": {
    "ejs": "^2.5.6",
    "express": "^4.15.3"
  }
}

Next to each installed module is its version number. You might also see a symbol such as * or ~. When you run npm install from the package.json these symbols give some flexibility to the version that can be downloaded.

= or v  This makes sure that exactly the same version of the package is installed. For example v2.5.6 would make sure that version 2.5.6 of the package is downloaded.

~  This fixes the major and minor version but allows for a higher patched version. For example, ~2.5.6 would make sure that the version installed would be greater or equal to 2.5.6 but less than 2.6.0.

^  This fixes the major version number but allows for a different minor or patched version. For example, ^2.5.6 would make sure the installed version could be greater or equal to 2.5.6 and less than 3.0.0.

*  This is a wildcard so it means that any version can be installed. For example, 2.* means that any version starting with 2 can be installed.

Setting Up a WebSocket With Socket.io

Now back to creating an application. At the moment the server passes the web page data when it loads. If the data updated, the web page would not reflect the change. You could write a script that pinged the server at regular intervals to see if there is a change but that wouldn’t be efficient; you would be making wasted calls if there was no new data and when new data does arrive the page would have to wait until the next call to be updated.

The WebSocket protocol solves this: new data will be sent straight to the web page and the page can send data back to the server to update other browsers connected to the server. This book will be using the socket.io library to make web socket calls.

First, socket.io needs to be installed as socket.io is not installed with Node.js.
  1. 1.

    Open a console window and navigate to the root of your application.

     
  2. 2.

    At the prompt type npm install [email protected] –save.

     

You can now include socket.io into the index.js file. Index.js will no longer be using the variables title and componentArray to send data to the browser, so they can be deleted. The app.get function is also updated so the variables are no longer being sent to index.ejs. Update the index.js file so it matches the code in Listing 2-4, and the new code is in bold:

var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
  res.render('index')
});
io.on('connection', function(socket){
    console.log('Connection to client established');
    socket.on('disconnect',function(){
        console.log('Server has disconnected');
    });
});
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});
Listing 2-4

index.js updated

The Code Explained

Socket.io changes the way that the data is passed to the browser; it is no longer sent in the route but via a socket (Table 2-8).
Table 2-8

index.js updated code explained

var io = require('socket.io')(server);

This code includes socket.io and attaches the server to it.

app.get('/', function (req, res) {

      res.render('index')

});

This creates a route from the server to the index.ejs page at the URL root. This time you are not sending the data through the route.

io.on('connection', function(socket){

    console.log('Connection to client established');

The io.on function will tell the socket what to do when there is connection by the web page to a server. You will see a console log each time a browser connects to the server.

socket.on('disconnect',function(){

    console.log('Server has

    disconnected');

});

This function will run when a browser disconnects to the server.

Rewrite The Index.ejs File To Include Socket.io

The index.ejs needs to display data coming from the socket. You no longer need the CSS or a number of the HTML components that were displaying the data from the server. There are new HTML components that will display the data from the socket. The socket uses JavaScript. There has to be a corresponding socket in the index.ejs file that references the socket in index.js, so there has to be a reference to socket.io in index.ejs. The <script></script> tags are used to add JavaScript code into index.ejs (see Table 2-9). Update index.ejs with the code in Listing 2-5, and notice that a lot of the code from the previous version of index.ejs has been deleted.

<!DOCTYPE html>
<head>
    <title>WebSockets</title>
</head>
<body>
    <div class="wrapper">
        <h1>Using socket.io</h1>
        <p>This page will update with socket.io</p>
    </div>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script>
    var socket = io();
</script>
</body>
</html>
Listing 2-5

index.ejs

The Code Explained

In the console make sure you are at the root of the application and start the application.

Try opening and closing the page on different web browsers and browser tabs and have a look at the console. Every time there is a new connection to the server ,you should see Connection to client established. Every time you close the connection to the serve by closing the page, you should see Server has disconnected.
Table 2-9

index.ejs code explained

<script src=" https://cdn.socket.io/socket.io-1.2.0.js ”></script>

Calls in the socket.io library to the web page; without this the page wouldn’t have access to the library.

var socket = io();

Creates a variable for the socket.io functions.

How Sockets Work

Socket.io has a number of functions that broadcast and listen for data. socket.emit broadcasts data and socket.on listens for data.

The functions use a matching pair of id’s on the server and the browser. These matching pairs of id’s will listen for updates from each other and can send data to each other.

The structure is:

socket.emit('an_example_id', message);
socket.on('an_ example_id', function(message){
      Do something with the message from socket.emit
});

socket.emit will send the data to the function socket.on with a matching id. Socket.on will listen for data from socket.emit with a matching id.

This means you can have multiple sockets with different ids and the data doesn’t get confused between the different sockets.

Sending Data To a Web Page With Socket.io

You will now create a simple socket on the server and on the browser page that will pass information between them. There will be a button on the web page that will update a number when it is clicked. The message that the button has been clicked will be sent to the server via socket.io. The number will be changed and then socket.io on the server side will send the information back to the connected web pages.

In index.js add in the code in bold:

var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
  res.render('index')
});
var buttonValue = 0;
io.on('connection', function(socket){
    console.log('Connection to client established');
    io.emit('clicked message', buttonValue);
    socket.on('clicked message', function(msg){
          buttonValue = 1 - buttonValue;
            io.emit('clicked message', buttonValue);
            console.log('Received message from client!',msg);
    });
socket.on('disconnect',function(){
        console.log('Server has disconnected');
    });
});
server.listen(3000, function() {
  console.log('Listening on port 3000...');
});

The Code Explained

Table 2-10 breaks down the code you just added.
Table 2-10

index.js code explained

var buttonValue = 0;

This variable holds a value that will be changed by someone clicking a button on a browser.

socket.on('clicked message', function(msg){

buttonValue = 1 -   buttonValue;

    io.emit('clicked message', buttonValue);

    console.log('Received message from client!', buttonValue);

});

In this code the socket id is ‘clicked message’. This socket will be listening for messages from the browser sent by a function io.emit(‘clicked message’, msg).

When it receives one it will carry out the instruction buttonValue = 1 - buttonValue; this will change the value of buttonValue to either zero or one. It will then send out the new value using io.emit(‘clicked message’, buttonValue) to the web browsers listening for the change.

The index.ejs from Listing 2-5 also needs to be updated with the code in bold:

<!DOCTYPE html>
<head>
    <title>WebSockets</title>
</head>
<body>
    <div class="wrapper">
        <h1>Using socket.io</h1>
        <p>This page will update with socket.io</p>
        <button id="clicked">click me</button>
        <div id="updates"></div>
    </div>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script>
    var socket = io();
    var button = document.getElementById('clicked');
    button.onclick = function(e){
        socket.emit('clicked message', 'clicked');
    }
    socket.on('clicked message', function(msg){
        document.getElementById('updates').innerHTML = msg;
    });
</script>
</body>
</html>

The Code Explained

You should now have a working server that interacts with and updates a web page (Table 2-11). If you click on the button on the page, it will update and also update other pages with the same URL; you should also see a message in your console.
Table 2-11

index.ejs code explained

var button = document.getElementById('clicked');

This line of code is some basic JavaScript. In the HTML there is a button element with an id of ‘clicked’. The variable button will hold a reference to this element so it can be referenced in the JavaScript.

button.onclick = function(e){

    socket.emit('clicked    message','clicked');

}

onclick is a function that is executed when the button on the web page is clicked. The function socket.emit('clicked message', ‘clicked’); is called. This will pass the message ‘clicked’ to the server to its matching socket.io function socket.on(‘clicked message’) .

socket.on('clicked message', function(msg){document.getElementById('updates').innerHTML = msg;     });

This code is listening to messages from the server with an id of ‘clicked message’ and when it gets one it uses the JavaScript function document.getElementById to find an element on the page with an id of ‘updates’ and change its inner html to the data passed in from the server.

Summary

This chapter introduced you to web technologies and how to create a web server to send data to and from a web browser.

You will use these skills in the next chapter to create a server that will import data from an Arduino and display it on a web page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.222.195