- 0 Deprecated
- 1 Experimental
- 2 Unstable
- 3 Stable
- 4 API Frozen
- 5 Locked
Los módulos
- Buffer - Permite el trabajo con datos crudos
- C/C++ Addons - Permite integrar librerias de C/C++
- Child Processes - Permite crear y gestionar "procesos hijo"
- Cluster - Permite gestionar nuestro proceso principal e "hijos" entre diversos módulos
- Command Line Options - Controla el lanzamiento de Node por Consola
- Console - Permite trabajar con la consola (terminal), imitando la consola del navegador
- Crypto - Relacionado a las funcionalidades de criptografía necesarias apra algunso protocolos como SSL
- Debugger - Utilidades de depuración
- DNS - Gestion y resolución de nombres de Dominios
- Domain - DEPRECIADO
- Errors - Gestión de errores
- Events - Permite gestionar y crear eventos
- File System - Permite manipular y crear ficheros en el sistema
- Globals - Ámbito global
- HTTP - Gestión del protocolo HTTP
- HTTPS - Gestión del protocolo HTTPS (http y tls/ssl)
- Modules - Gestión y carga de módulos
- Net - Nos aporta una capa de red asíncrona y permite gestionar "streams" tanto cliente como servidor.
- OS - Información básica sobre el sistema operativo en el que estamos funcionando
- Path - Gestión de rutas dentro del sistema (navegación de carpetas y archivos)
- Process - Objeto global que gestiona el proceso del sistema que representa nuestra ejecución de Node
- Punycode - Sintaxís de codificación a RFC 3492 y RFC 5891
- Query Strings - Manipualción y gestion de cadenas URL
- Readline - Puede leer línea a línea información de entrada como la consola
- REPL - Read-Eval-Print-Loop (REPL)
- Stream - Interfaz abstracta usada por otros módulos para gestionar el flujo de la información
- Timers - Funciones globales de tiempo como setInterval, clearInterval, etc...
- TLS/SSL - Capa de encriptación basada en OpenSSL
- UDP/Datagram - Gestión del protocolo UDP
- URL - Facilita la resolución y parseo de URLs
- Utilities - Utilidades varias, la mayoría depreciadas
- V8 - Información sobre v8
- VM - Permite aislar código en "sandboxes"
- ZLIB - Permite trabajar con Gzip/Gunzip, Deflate/Inflate y DeflateRaw/InflateRaw
- Hello World con HTTP:
var http = require('http');
var puerto = 3000;
var direccion = "127.0.0.1";
var mensaje = 'Hola a todos, ahora usando HTTP\n';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(mensaje);
}).listen(puerto, direccion);
console.log('Server running at http://'+direccion+':'+puerto+'/');
- Hello World desde c9.io:
var http = require('http');
var mensaje = 'Hola a todos, ahora usando HTTP con C9.io\n';
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(mensaje);
}).listen(process.env.PORT, process.env.IP);
console.log('Server running at http://'+process.env.IP+':'+process.env.PORT+'/');
- Rediccionamiento:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(301, {
'Location': 'http://www.google.es/'
});
res.end();
}).listen(process.env.PORT, process.env.IP);
console.log('Servidor funcionando en http://'+process.env.IP+':'+process.env.PORT+'/');
- Ping (petición http):
var url = "google.es";
http.get({ host: url }, function(resOrigen) {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("La respuesta de " +url+" es "+resOrigen.statusCode );
console.log("La respuesta de " +url+" es "+resOrigen.statusCode );
}).listen(process.env.PORT, process.env.IP);
console.log('Servidor disponible en http://'+process.env.IP+':'+process.env.PORT+'/');
}).on('error', function(e) {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("La respuesta de " +url+" genera un error - " + e.message );
}).listen(process.env.PORT, process.env.IP);
console.log('Servidor disponible en http://'+process.env.IP+':'+process.env.PORT+'/');
console.log("Tenemos un error!! - " + e.message);
});
- Leyendo urls:
var url = require('url');
var demoURL = "http://localhost:3000/ruta?parametro=dato#detalle";
console.log("El host: "+url.parse(demoURL).hostname);
console.log("El puerto: "+url.parse(demoURL).port);
console.log("La ruta: "+url.parse(demoURL).pathname);
console.log("La parametro: "+url.parse(demoURL).query);
console.log("El hash(#): "+url.parse(demoURL).hash);
- Trabajando con rutas:
var http = require('http'),
url = require('url');
http.createServer(function (req, res) {
var pathname = url.parse(req.url).pathname;
if (pathname === '/') {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Index!');
} else if (pathname === '/otro') {
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf-8'
});
res.end('sencillamente otra página');
} else if (pathname === '/alindex') {
res.writeHead(301, {
'Location': '/'
});
res.end();
} else {
res.writeHead(404, {
'Content-Type': 'text/plain'
});
res.end('Querido... 404!');
}
}).listen(process.env.PORT, process.env.IP);
console.log('Servidor funcionando en http://'+process.env.IP+':'+process.env.PORT+'/');
- Ping recurrente (consola):
var http = require('http');
var url = "google.es";
var tiempo = 3500;
setInterval(function() {
http.get({ host: url }, function(res) {
if (res.statusCode === 200 ) {
console.log("Sin errores en " +url);
} else {
console.log("Respuesta Http "+res.statusCode+" en " +url);
}
}).on('error', function(e) {
console.log("Con errores -> La respuesta de "+url+" es "+e.message );
});
}, tiempo);
El modelo de programación de Node.js es monohilo, asíncrono y dirigido por eventos.
- No puede haber código bloqueante o todo el servidor quedará bloqueado y esto incluye no responder a nuevas peticiones entrantes.
- La asincronicidad implica que no sabemos cuándo ni en que orden se va a ejecutar el código, generalmente esto no es importante pero en ocasiones sí lo es y habrá que tenerlo en cuenta.
- En caso de error inesperado debemos capturarlo y controlar el posible estado en que haya podido quedar la ejecución del código.
Nicolas Nombela en nnombela
- Sincrónico - código bloqueante:
var http = require("http");
var numeroPeticion = 1
function writeResponse(response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hola Mundo!, numero de peticion "+numeroPeticion);
response.end();
console.log("Se termino... "+numeroPeticion);
}
function sleepSynch(seconds, response) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + Math.floor((Math.random() * 1000) + 500) * seconds) {
// Nada pasa....
}
writeResponse(response);
}
http.createServer(function(request, response) {
console.log("Empezo... "+numeroPeticion);
sleepSynch(10, response);
numeroPeticion++;
}).listen(process.env.PORT);
console.log("en puerto ->" + process.env.PORT);
- Asincronico - timeOut()
var http = require("http");
function writeResponse(response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hola Mundo!");
response.end();
console.log("Se termino... ");
}
function sleepAsynch(seconds, response) {
setTimeout(function() {
writeResponse(response);
}, Math.floor((Math.random() * 1000) + 100) * seconds);
}
http.createServer(function(request, response) {
console.log("Empezo... ");
sleepAsynch(10, response);
}).listen(process.env.PORT);
console.log("en puerto ->" + process.env.PORT);
- Se cierra:
setTimeout(function (){
process.stdout.write("Cerrando Node...")
}, 1000)
- Se mantiene:
setInterval(function (){
// Nada pasa... pero sigo funcionando
}, 1000)
- Programando una salida:
var contador = 0
setInterval(function (){
contador++
if(contador > 10){
process.exit()
} else {
console.log("Sigo. Valor contador -> "+contador +"\n")
}
}, 1000);
- Leer un archivo
var fs = require('fs');
fs.readFile('archivo.txt', 'utf8', function (err, data) {
if (!err) {
console.log(data);
} else {
throw err;
}
});
- Escribir un archivo
var fs = require('fs'),
data = "y esto... se guardará en el archivo.txt";
fs.writeFile('archivo.txt', data, function (err) {
if (!err) {
console.log('Datos guardados en el archivo.txt');
} else {
throw err;
}
});
- Usando Promesas y Callbacks
var fs = require("fs");
// Con CallBacks!
fs.readFile("./miArchivo.txt", function(error, content){
console.log("Leyendo el archivo...");
fs.writeFile("./logitud.txt", content.length, function(error){
if (error) {
console.log("error! ", error);
} else {
console.log("Terminado... hemos almacenado una cadena que vale ",content.length);
}
});
});
// Con Promesas!
function leerArchivo (nombre) {
return new Promise(function(resolver, rechazar){
fs.readFile(nombre, function(error, contenido) {
console.log("Empezando la lectura de ", nombre);
if(error){
console.log("Error en la lectura");
return rechazar(error);
}
console.log("Lectura finalizada en ", nombre);
resolver(contenido);
});
});
}
function escribirArchivo (nombre, contenido){
return new Promise(function(resolver, rechazar){
fs.writeFile(nombre, contenido, function(error){
if(error){
console.log("Error en la escritura de ", nombre);
rechazar(error);
} else {
console.log("Escritura Termianda en ", nombre);
resolver();
}
});
});
}
//Opción1
leerArchivo("./miArchivo.txt")
.then(function(contenido){
escribirArchivo("./longitud.txt", contenido);
})
.catch(function(error){
console.log("Promesas con errores: ");
console.log(error);
});
//Opción2
Promise.all([
leerArchivo("./otros.txt"),
leerArchivo("./usuarios.txt"),
leerArchivo("./mas_cosas.txt")
]).then(function(respuestas){
console.log("Tenemos un total de "+respuestas.length+" respuesta/s.");
console.log("El primero tiene "+respuestas[0].length+" caracteres");
console.log("El segundo tiene "+respuestas[1].length+" caracteres");
console.log("El tercero tiene "+respuestas[2].length+" caracteres");
});
//Opcion3
Promise.race([
leerArchivo("./otros.txt"),
leerArchivo("./usuarios.txt"),
leerArchivo("./mas_cosas.txt")
]).then(function(respuesta){
console.log("El más rápido tiene solo "+respuesta.length+" caracteres.");
});
- Más métodos para:
- Síncronos
- Escucha de cambios
- Manipulación de carpetas
- etc...
-
Patrón Observador
-
Similar al navegador
-
Suscribiendonos a eventos
- Sin eventos
var http = require('http'); var server = http.createServer(function (request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end("¡Hola people!"); }).listen(process.env.PORT); console.log('Servidor escuchando por el puerto ' +process.env.PORT);
- Con eventos
var http = require('http'); var server = http.createServer().listen(process.env.PORT); server.on('request', function (request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end("¡Hola people!"); }); console.log('Servidor escuchando por el puerto ' +process.env.PORT);
-
Ejemplo sencillo: Creando nuestros eventos
var eventos = require('events');
var EmisorEventos = eventos.EventEmitter;
var ee = new EmisorEventos();
ee.on('datos', function(fecha){
console.log(fecha);
});
setInterval(function(){
ee.emit('datos', Date.now());
}, 500);
- Ejemplo: Juguemos al Ping-Pong
var EventEmitter = require('events').EventEmitter;
var pingPong = new EventEmitter();
var pingNumero = 1;
console.log('Bienvenido al juego de Ping/Pong!');
console.log('Empezamos en 5 segundos....');
setTimeout(function(){
console.log('Primer Ping... que desencadenará el juego');
pingPong.emit('ping', pingNumero);
pingNumero++;
}, 5000);
pingPong.on('ping', function(numero) {
console.log('Llegó el Ping('+numero+'). Emitimos Pong');
setTimeout(function(){
pingPong.emit('pong');
}, 1000);
});
pingPong.on('pong', function() {
console.log('Llegó el Pong. Emitimos Ping');
setTimeout(function(){
pingPong.emit('ping', pingNumero);
pingNumero++;
}, 1000);
});
var pingLogger = function(numero) {
console.log('Llegó el Ping ('+numero+') al nuevo listener');
}
setTimeout(function(){
console.log('Añadiendo un nuevo listener a Ping');
pingPong.on('ping', pingLogger);
}, 10000);
setTimeout(function(){
console.log('Eliminando el último listener');
pingPong.removeListener('ping', pingLogger);
}, 12000);
console.log('Nota: Recuerda que los Eventos nos ayudan con la asincronía, ¿no?');
1 - Crea las rutas básicas para tener una página web clásica (¿Quienes somos? | ¿Donde Estamos? | ¿Que hacemos? | Contacto... etc...)
// Tu solución