Node.js, a new ecosystem based on JavaScript
This is a server written in JavaScript, but it could be much more than that.
Node.js can run locally on Windows and Linux. It interacts with a browser and you can create applications in JavaScript, running locally or remotely and use that with HTML 5 and Canvas interfaces. We will develop this possibility and its implications.
Node.js is not really a replacement for Apache but rather a tool for webmasters who want a full control over what happens on the remote server, or have some kind of local server for applications operating simultaneously and sharing data. MySpace is an example of a site running Node.js, with the Express framework. Groupon has in 2013 migrated from Rail to Node.js and so became one of the largest sites with this system. Among other big sites using Node are Paypal, Yahoo.
Node.js is an application server
This is a server written in JavaScript, which can be used as a library of a program written in any language.
With the V8 JIT compiler, it can interpret scripts in JavaScript. It itself is interpreted by V8. Technically, this is a library added to V8 and encapsulated in a launcher.
It is events driven, a unique thread is open for each process. It works asynchronously, each event triggers a process that runs independently of the others. It is also non-blocking, which means that one does not need to lock something to prevent further access when an operation is performed, as it is the case in multi-threading.
It can be installed on a server instead of Apache where one will give the URLs of pages to load and run applications. These will be executed in the browser on the local machine.
It can be installed locally too, this is easier than Apache, it is just an executable file that run at command line to make it available to the browser, with a local IP and port number.
It is less complete than Apache, it is sometimes necessary to add code to handle operations that are already performed by Apache (for version 6.0 of Node.js), or to add a framework.
It is protocol-independent, can use HTTP to serve HTML pages or other protocols for other types of applications.
The functioning is described in the schema below. A JavaScript script creates an instance of server and open a port through which a browser or other user agent can communicate with the script.
Node.js is used by giving it a JavaScript program to interpret
Suppose you create a script that will be called myscript.js. You launch the server at command line as follows:
node myscript.js
The script should contain code to create an instance of server, eg:
var http = require('http'); function f(request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.write(new Date() +'\nServer online...'); response.end(); } var server = http.createServer(f); server.listen(1000);
A server is created in this way:
- Loading a module for a server using the http protocol, and assigning it to a variable.
- Creating an HTTP server by calling the createServer method of the http server object, with the command: server.createServer ().
This method use for parameter a function that is called by the server object with two objects as parameters (which are named in the example request and response). - The writeHead method of the response object creates a header with the HTTP status code 200 which means OK.
- The write method displays a message.
- The end method command the end of sending data from the server (no the communication). It can also display a message as write.
- The request object is not used here, but it provides access to useful functions. See the next example.
- A port is assigned in the listen method of the server object: server.listen(1000).
The number 1000 is an example, other values between 0 and 65535 are possible, provided that the number is not already used by another service.
The parameters of createServer is a function that sends a message to the user. It may be writen as anonymous function, it is used as a parameter by an internal function to the server object that contains the request and response objects that remain assigned after the return of the function f.
The code takes advantage of closures inherent in JavaScript. The closure is a mean to provide a global scope for variables declared in a function, but making them accessible only to this function. If we call the function several times, the variables retain their value from one call to another. Thus a process can run sandboxed, independently of the others.
To access the application, type in the URL bar of a browser:
127.0.0.1:1000
Which corresponds to the local IP followed by the chosen port number. It will display the date and time, followed by the message "Server online ...". Or also:
localhost:1000
This URL will remain available while the node myscript.js command is not canceled or the command line window closed. If another script is run, with node script2.js for example, by refreshing the page we then obtain access to this new script.
Demo: How to get persistence of data
A script to show how data can persist from a connection to another.
But first, we have to complete the header of the previous script, to support accents and other foreign codes in order to integrate some text in our simplified interface:
response.writeHead(200, {'Content-Type': 'text/plain;charset=utf-8'});
Charset UTF-8 can support most characters.
We will add a connection counter and display the counter, and we can verify that the data created during a connection is kept for the following, which is essential before they can share data between applications.
To test the example, repeatedly reload the page in the browser with the URL given above.
var http = require('http'); var counter = 0; function f(req, response) { if(request.url == '/favicon.ico') return; response.writeHead(200, {'Content-Type': 'text/plain;charset=utf-8'}); if(counter == 0) response.write(new Date() +'\nServer online...\nFirst connection.'); else response.write((counter + 1) + " connections."); counter++; response.end(); } var server = http.createServer(f); server.listen(1000);
Counter is a global variable. At the first connection, the introductory message is displayed, at the following, only the connection number is displayed.
The first line ...
if(request.url == '/favicon.ico') return;
... is used to remove a side effects: the fact that the browser when you load a page, makes two successive requests, one for the page, one for the favicon, which increments the counter twice!
One can access the URL from multiple browsers while maintaining data persistence.
You can also access the server without a browser. You can for example, locally, with a script in PHP, use curl to interact with the server, along with a browser. This will be the subject of another article.
While the server is active (when it is online it makes sense to remain permanently), you can communicate with different browsers or other kinds of user agents.
Next part: How to build a page and application server script.
Get the source code
- The files myscript.js and persistence.js correspond to the first and second examples respectively.
Useful modules
With npm included in the archive, you can automatically add modules to complete the server.
- Step. Allows to order a set of action either in series or in parallel. This makes for a clearer view of asynchrone actions.
- Async. To control the flow in parallel or series.
- Express. Framework of apps.
Resources and documents
- A sandbox to test a code.
- Node.green. Real time (almost) status of ECMAScript implementation for each version of Node.
- Node/Chackra. A version of Node by Microsoft with V8 replaced by Chackra, for Windows 10.