• Introduccion a NodeJs.
  • Principios de funcionamiento.
  • Server basico http.
  • Carga de dependencias .
  • Rest API con ExpressJS.
  • Comunicacion en tiempo real con SocketIO.


Agenda

  • En palabras no tan simples Node.js es:
    • Un framework para aplicaciones de alto rendimiento, optimizado para entornos de alta concurrencia.

 

  • Desde el sitio oficial:
    • 'El objetivo de nodeJS es proporcionar una manera fácil de crear programas de red escalables' - (! De nodejs.org)
  • En palabras simples Node.js es:
    • javaScript del lado del servidor .

Introdución: Basica

Introdución: Avanzada

  • Node.js utiliza un modelo orientado-a-eventos sin bloqueo de E/S.

 

  • Hace uso del llamado bucles-de-eventos a traves de callbacks para implementar el anti-bloqueo de E/S.

 

  • No hay implementación DOM proporcionada por Node.js     var elemento = document.getElementById ("elementId");

 

  • Todo dentro de Node.js se ejecuta en un solo hilo (single-thread).
var fs = require('fs');
fs.readFile('/etc/passwd', function(err, buf) {
  console.log(buf.toString()); // Se ejecuta cuando se termine de leer el archivo
});

console.log("Hello!"); //Se ejecuta sin espera
var fs = require('fs');
var contents = fs.readFileSync('/etc/passwd').toString();
console.log(contents); //esperamos por el resultado
console.log("Hello!"); //ejecucion bloqueada

Ejemplo de bloqueo de E/S

Para tener en cuenta

  • Node.js no es "la" plataforma o "silver bullet" que dominará el mundo del desarrollo web.

 

  • Definitivamente utilizar Node.js para operaciones intensivas de CPU anula casi todas sus ventajas.

 

  • Donde Node.js realmente brilla es en la construcción de aplicaciones de red escalables por su capacidad de manejar un gran número de conexiones simultáneas con un alto rendimiento.

Funcionamiento de servidores tradicionales

Funcionamiento de servidor node.js

Funcionamiento del event-loop

Server http

var http = require("http");

http.createServer(function(req, resp) {
  resp.writeHead(200, {"Content-Type": "text/html"});
  resp.write("Hola Mundo");
  resp.end();
}).listen(8888);

Echo server http

var http = require('http');

http.createServer(function (req, res) {

    req.on('data',function(message){
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write(message);
      res.end();
      console.log(message.toString());
   });

}).listen(80);

console.log('Server listening on port 80');

Carga de dependencias

NodeJS - utiliza la implementacion de carga 

modulos basado en CommonJS 

 

  1. El codigo usa "require" para incluir los modulos o dependencias
  2. Los modules usan "exports" para hacer los modulos disponibles 
  // hello.js
    console.log('Hello World');
// app.js
    require('hello.js');

El modulo mas simple

 // bar.js
    module.exports = function () {
      console.log('bar!');
    }
 // app.js
    var bar = require('./bar.js');
    bar();

  Exportando una funcion anonima

 // doo.js
    var Doo = function () {};

    Doo.prototype.log = function () {
        console.log('doo!');
    }

    module.exports = Doo;
 // app.js
    var Doo = require('./doo.js');
    var doo = new Doo();
    doo.log();

  Exportando un prototype

El "Revealing Module Pattern"

module.exports = (function() {
    
     var text = "Hello world!"
    
    var private= function() {
        console.log("private method executed")
    };

    var public= function() {
        console.log(text);
        private();
    };
    
    return {
        public: public
    };

})(); 
module.exports = module;

El gran repositorio de modulos

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('Hello World');
});

var server = app.listen(80, function () {
   console.log('listening port: ', server.address().port);
});

Hello World con ExpressJs

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.post('/', function (req, res) {
  res.send('Got a POST request');
});

app.put('/user', function (req, res) {
  res.send('Got a PUT request at /user');
});

app.delete('/user', function (req, res) {
  res.send('Got a DELETE request at /user');
});

var server = app.listen(80, function () {
   console.log('listening port: ', server.address().port);
});

Hello World con ExpressJs

Problema: ¿como armar un chat web?

VS

Long-polling

Web Sockets

Solucion: node y web sockets 

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(80, function(){
  console.log('listening on *:80');
});

Paso1 - Armar un server simple

 app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

Paso2: Agregar una pagina como recurso

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>   
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

Paso3 - Agregar websockets

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

http.listen(80, function(){
  console.log('listening on *:80');
});

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
  
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
    
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
    io.emit('chat message', msg);
  });
  
});

Paso4: Actualizar nuestra pagina

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>   
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="message" autocomplete="off" /><button>Send</button>
    </form>
    <script src="http://cdn.socket.io/socket.io-1.2.0.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#message').val());
        $('#message').val('');
        return false;
      });
      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
    </script>
  </body>
</html>

Armemos nuestro server en un host

https://github.com/JavascriptLitoral/chat-example

Challenge

  • Transmitir un mensaje a los usuarios conectados cuando alguien se conecta o se desconecta
  • Añadir soporte para apodos
  • No envíar el mismo mensaje al usuario que lo envió a sí mismo 
  • Mostrar quién está en línea
  • Añadir mensajería privado

NodeJS

By Mariano Ravinale