• 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.

 

  *  Mas info: http://goo.gl/un4pJw

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();
 // 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

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
Made with Slides.com