Introducing Nodejs!

This post is intended for those who want to start learning Node.js or just want to know what it is, so here we go!

What is Nodejs ?

Nodejs is a platform built on Chrome’s V8 JavaScript runime. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.

Event- driven programming

It is also a programming paradigm in which the flow of the program is determined by events, which can be user actions, sensors or other programs interactions.

Today, this concept is largely used in GUI applications where a mechanism is in place to listen for events and executes an action once the event occurs. This is a key feature in node.js !

In most software platformw, in the backend field, every system call, such as reading or writing a file, querying a database, is blocked. The program execution will stop and wait for the call to finish and return results. This is blocking I/O and synchronous programming.

This turns outt to be quite expenseive! What Node does is reducing the overhead of waiting for I/O.

Node.js serves all the requests from a single thread. The program code running in this thread is still synchronously but every time a system call takes place, it will be delegated to the event loop along with a callback function. The main thread is not put to sleep and keeps serving other requests. As soon as the previous system call is completed, the event loop will execute the callback passed. This callback will usually deal with the result returned and continue the program flow.

Event Loop

Node has the ability to handle highly concurrent requests through the always running “single-threaded” event loop. Event-driven apps have generally a main loop that listens for events and then triggers a callback function when an event is detected.

event-loop

The event loop iterates over the event queue and if an item requires an in or out operation, the event loop just delegates the operation to the thread pool and continues his execution, once the I/O operation is complete, the callback is queued for processing and then executed providing the expected results.

Event Emmiters

If you have some js background, you are already familiarized with the concept of events, in the DOM we use to manage this events, for example the click event (as we previously mentioned). In node we have objects that produce events in a similar way.

All this objects are instances of event.EventEmitter.

EventEmitter class lives in the events module of Node. In Node we have objects that use events by default, for example net.Server, it has an event that triggers each time a peer connects. We can also create new ones by importing this class in ours own modules:

var events = require('events');
var eventEmitter = new events.EventEmitter();

Let's create an event an attach to it, for example an error log:
   
var eventEmitter =  require('events').EventEmitter;
var log = new eventEmitter();

/*LISTENER*/

log.on("error",function(msg){

console.log("error",msg)

});

/*EMITTING EVENT*/

log.emit("error","Error Msg");


Streams

When we work with apps that need to manage massive data network flow- such as files- to upload efficiently, it is better to work with the data piece by piece and process them in the moment that those pieces are occuring.

We have basically 2 types of streams, write (writableStream) and read (readableStream. In addition streams implement EventEmitter, that means that we can create or attach to new events! This make streams a real powerful tool as well.

In order to create an example we are going to use 2 stream known events: “readable” and “end”.

In this example we are creating a server listening in the port 8080, using the http module of node and the createServer method. This method receives a function with 2 parameters, a readable parameter and a writable parameter, they are “request” and “response”.

var http = require(http);
http.createServer(function(request,response){
    response.writeHead(200);
    request.on("readable",function(){
            var piece= null;
            //while read
            while(null !== (piece= request.read())){
            //print de piece
            response.write(piece);// when we read we write on response
        }
    });

    request.on("end",function(){
        // when we finish we return response.
        response.end();
    });
}).listen(8080);

PIPE

The pipe tool allows us to do the same that we did previously but saving lines of code, this is a powerful thing because we can write a writableStream at the same moment that we are reading a readableStream, while the previous code remains like this :

 var http = require(http);
http.createServer(function(request,response){
   response.writeHead(200);
   request.pipe(response);
}).listen(8080);

Using Streams in the file system

The logic is similar to the one we used with Pipe, the only difference is that we need to use the fs module of node.

Node implements File I/O using simple wrappers around standard POSIX functions. The Node File System (fs) module can be imported using the following syntax

var fs = require(“fs”);

Example using pipe to create a file, reading from another file :

var fs = require(“fs”);
var from= fs.createReadStream(“path.txt”);
var to= fs.createWriteStream(“newPath.txt”);
from.pipe(to); //copy of file

Combining all this concepts!

The main idea is to combine all this things to do an update file :),shall we do it?

Let’s go.

Data flow

Let’s imagine our  client sends a piece of file to the server. The file in server will not be saved in memory, instead it is stored in the file system at that exact moment!

The file pieces flow until the transfer on the file is complete, and since it is event-oriented, all this process is non blocking! This means that we can upload various file simultaneously!

nodefile

Example :

In order to do the update function, we need to import the http module for the server creation and the fs to use the filesystem.

var http = require(“http”);
var fs = require(“fs”);

http.createServer(function(request,response){
   var target = fs.createWriteStream(“brim.txt”);
   request.pipe(target );
 request.on("end",function(){ // this is not needed because the pipe already do this... but i want to put a message when the upload is complete
        response.end(“archivo subido con éxito”); 
   });
}).listen(8080);

Express

Express is a framework used to develop minimal and flexible apps,  useful to use an mvc architecture, express helps us to manage routes, resolve requests and manage views.

Example :

var express = require("express");
var app = express();
app.get("/",function(request,response){
		response.sendFile(__dirname + "index.html")
	});
app.listen(8080);

Socket.io (real-time apps)

It allows us to create a connection with each client of the server. With this connection we can send and receive data from the client to the server and viceversa.

To work with the browser websockets we are going to use the socket.io node library:

we want to share same server between client and server.

server code :
var express = require("express");
var app = express();
var server = require("http").createServer(app); //
var io = require(socket.io)(server)

io.on("connection",function(cliente){
	console.log("Client connected....");
});
 
app.get("/",function(req,res){
	res.sendFile(__dirname + "/index.html");
});

server.listen(8080);

Client-side code:

In the HTML that we are sending, we need to include the script of the socket.io library to listen and emit events client-side. In order to do that in the index.html file, we need to include this :

 <script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect("http://localhost:8080");
</script>


Emit from server and listening in client
       io.on("connection",function(client){ console.log("client connected...."); cliente.emit("messages",{msg: "hi!"}); });

               //listening in client

<script src=”/socket.io/socket.io.js”></script> <script> var socket = io.connect(“http://localhost:8080”); socket.on(“mensajes”,function(data){ alert(data); }); </script>

Emit from client and listening in server
    io.on("connection",function(client){ console.log("Client connected...."); cliente.emit("msgs",{msg: "hi!"}); client.on("msgs",function(data){ console.log(data); }); });

<script src=”/socket.io/socket.io.js”></script> <script> var socket = io.connect(“http://localhost:8080”);

$(“#sendSomething”).click(function(){ var mensaje = $(“#id”).val(); socket.emit(“msgs”,mensaje); }); </script>

Broadcasting

It’s important to know that we have a broadcast function in order to propagate information to all clients connected.

   client.on("msgs",function(data){
   client.broadcast.emit("msgs",data); //send data to connected clients
   });
   //listening bradcast in client
   <script src="/socket.io/socket.io.js"></script>
   <script>
   var socket = io.connect("http://localhost:8080");

   $("#send_chat").click(function(){
   var msgs = $("#chat_message").val();
   socket.emit("msgs",msgs);
   });

   socket.on("msgs",function(data){
   $("#room").append("<p>"+ data + "</p>");
   });
   </script>

Hope you ended up with a good idea of what Node.js is, and please if you have any questions, don’t hesitate in contacting us!!

Cavepot Team

Related posts

Comments are closed.