Check the new version here

Popular channels

Javascript, node.js y el ecosistema

Módulo 1

Presentación.
Hoy en día estamos escuchando o leyendos términos como Node.JS, mongoDB, Angular, Redis, fullstack, etc. pero no tenemos muy claro aún de que se trata todo esto. El objetivo de este documento es poder entender un poco de que se tratan estos terminos, cuales son las tendencias, beneficios, fortalezas, etc.

JavaScript.
Siempre se pensó que JavaScript era un lenguaje para validar formularios, hacer animaciones, etc. La verdad es que pensar que javascript solo sirve para esas cosas es muy injusto para el lenguaje. Como lenguaje de programación en sí es muy dinámico, facil de aprender y disponible en varias plataformas.
Hoy en día podemos encontrar javascript en navegadores web, plaquetas arduino (Jarduino), desktop (widgets), aplicaciones servidor (caso de node.js), mobile, etc.
Una de las características de JavaScript más importante es que es un lenguaje orientado a prototypes, es decir que es un estilo de programación orientada a objetos en la cual los objetos no nace de instancias sino de la clonación de otros objetos. El programador puede ir modificando el objeto a lo largo del runtime, clonarlo, referenciarlo, etc.


Que es Node.js?
Node.js es una solución para escribir aplicaciones de red escalables de manera rápida, resolviendo problemas de rendimiento, consumo y costo.
Cuenta con un motor V8 (El motor de JavaScript creado por Google https://code.google.com/p/v8/), y miles de módulos que se le pueden agregar al core.

Si bien las aplicaciones se escriben en javascript, una vez ejecutada la misma es compilada en runtime, obteniendo un rendimiento muy similar a aplicaciones escritas en C++.

http://www.realfreemarket.org/blog/2014/01/02/fsk-benchmark-test-cc-vs-javascript-vs-php/
http://wingolog.org/archives/2011/06/10/v8-is-faster-than-gcc
http://fabricengine.com/2011/11/server-performance-benchmarks/


Una gran ventaja es que un programador JavaScript puede trabajar tanto en backend como en frontend, reduciendo la cantidad de personas necesaria en un equipo, aumentando la comprensión del proyecto y obteniendo un mejor resultado.

Que NO es Node.js?
No es APACHE, no es Tomcat, no es un servidor pero podemos escribir código para generar un servidor de lo que queramos. No es un lenguaje de programación, sino una implementación del motor V8 en el server.
El modelo orientado a Eventos.
En los sistemas creados en PHP o Java cada vez que se realiza una conexión (entra un nuevo cliente) se genera un thread o fork para poder atender su petición. Esto en números de consumo significa ocupar entre 2 y 3MB de memoria RAM por cada "cliente".
En Node.js se utiliza el modelo de basado en Eventos, y cada vez que se genera una nueva conexión se disparan eventos, los cuales ejecutan rutinas ya cargadas en memoria.
Básicamente lo que esto quiere decir es que podemos con la misma máquina física soportar cientos de miles de conexión sin grandes problemas.





Programación asincrónica (async).
Gracias al modelo de eventos en node.js el tipo de programación que se utiliza es asincrónica, esto quiere decir que no tenemos que detener el flujo de ejecución de nuestra aplicación para realizar tareas como consultar a una base de datos, leer un archivo de disco o cualquier otra tarea de la que tengamos que “esperar” una respuesta.
Para que este concepto funcione vamos a hacer uso de los callbacks. Básicamente un callback es la función o grupo de rutinas que debemos ejecutar cuando un proceso asincrónico ha terminado. Dentro de un callback podemos incluir otros procesos asincrónicos que deberán contar con sus callbacks, etc.
Veramos un ejemplo de código async.


var fs = require('fs');

console.log("hola a todos");
console.log("Async power!");

var myText = "estoy programando en node.js de forma async";

fs.writeFile('test.txt', myText, function(err){

console.log('callback de fs.writeFile ', err);
});

console.log("termine de ejecutar");





En el ejemplo anterior vemos como se imprime en pantalla primero la leyenda “termine de ejecutar” que la leyenda “callback de fs.writeFile”. Eso sucede debido a que el proceso de abrir y escribir en un archivo es asincrónico y demora más que mostrar en pantalla una leyenda.









var http = require('http');

console.log("init http server");

http.createServer(function (req, res) {
console.log('Nuevo request: ', req.url);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("hola a todos");

}).listen(8888);

console.log('termino el script');




Este es uno de los ejemplos más comunes, un webserver escrito en Node.js.
Si prestamos atención veremos que por cada conexión se dispara un evento, el cual esta asociado a un callback (la function pasa como argumento al método createServer).
req y res son los argumentos de nuestro callback, req representa al request, y res representa la conexión en sí.

Es importante destacar que en este ejemplo nuestro script no termina nunca de correr, esto se debe a que hay un constante monitoreo (keep) de si existen nuevas conexiones. Lo mismo ocurre por ejemplo cuando nos conectamos a una base de datos, nuestro script se queda en ejecución hasta que no cerremos la conexión a la base de datos.

MongoDB
MongoDB es un motor NoSQL basado en documentos íntimamente relacionado con Node.js, como Oracle con Java.
Esta escrito en C++ y cuenta con un motor V8, por lo que la manera de interactuar con el motor es mediante JavaScript.
Cuando hablamos de documentos nos referimos a un json (JavaScript Object Notation), es decir una representación "gráfica" de un objeto.
Existen una serie de diferencias entre MongoDB y un sistema SQL (por ejemplo MySQL, SQL Server, etc).


http://docs.mongodb.org/manual/reference/sql-comparison/

Para entender mejor de que se trata MongoDB vamos a hacer los siguientes ejercicios, obviamente hay que contar con mongoDB instalado.

Primero que nada, descargamos los siguientes archivos.
http://lync.com.ar/examples/mongo/practica.txt
http://lync.com.ar/examples/mongo/gps.js
http://lync.com.ar/examples/mongo/httpgsp.js




var http = require('http');
var mongo = require('mongojs').connect('mongodb://127.0.0.1/pruebas', ['gps']);


console.log("init http server");

http.createServer(function (req, res) {
console.log('Nuevo request: ', req.url);
res.writeHead(200, {'Content-Type': 'text/plain'});
getMoviles(res);

}).listen(8888);

console.log('termino el script');

var getMoviles = function(res){

var query = { geoNear: "gps",
near: [ -60.64793, -32.93682 ],
spherical: true
,maxDistance : 0.00013665514701406524
,'query': {
'digitalStatus.free': true
, habilitado: 1
, 'positionAge.integer': { $lt: 2 }
, active:true
}
,includeLocs: true
,uniqueDocs : true
,num: 1
};


mongo.executeDbCommand(query, function(err, docs){
res.end(JSON.stringify(docs));
});

}




Node Package Manager (NPM)
Node.js cuenta con miles de módulos que brinda soluciones a prácticamente cualquier cosa que podamos necesitar.
NPM es el comando para poder operar con estos módulos, instalarlos, actualizarlos, crear nuestros propios paquetes, etc. Los módulos pueden ser globales (disponibles para todos nuestros proyectos) o locales (solo disponible para nuestro proyecto).

Vamos a ver dos paquetes muy interesantes para nuestros proyectos en Node.js, el primero es express.js y el segundo forever.

Forever
Forever es un módulo de node que permite lanzar apps en node.js que quedan residentes (por ejemplo un webserver) y monitorea al proceso. Si por alguna razón el proceso se detiene forever lo vuelve a lanzar.
Para instalar forever en forma global ejecutamos el siguiente comando:

server$ npm install forever -g

Recordemos que cuando instalamos un módulo en forma global vamos a requerir de privilegios de root en nuestro sistema.

Express.js

Express es un framework para crear aplicaciones web. Nos da soluciones a tareas comunes como servir archivos estáticos, routing, gzip, manejo de cookies, sesiones, etc. Nota: Varios de estos modulos (middlewares), fueron separados del core de express en su última versión (4) y deben de ser instalados por separado (body-parser, compression, cookie-parser, cookie-session, method-override, serve-favicon, serve-static, etc).

Para instalarlo solo debemos ejecutar:
server$ npm install express

Veamos nuestro primer script usando express.js

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

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

var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});




Esto genera un simple webserver que mapea la url /hello.txt y devuelve el mensaje “Hello World”.
El servidor web corre en el puerto 3000.

Finalmente vamos a ver un ejemplo que complementa todo lo repasado hasta el momento.
Vamos a usar Express.js para montar una aplicacion web, usaremos una librería para mongodb llamada mongosee y crearemos dos métodos simples.
var mongoose = require('mongoose'),
express = require('express');

mongoose.connect('mongodb://localhost:27017/test');

var app = express();

var PersonSchema = { name: String };
var Person = mongoose.model('Person', PersonSchema);

app.get('/user/:username',function(req,res,next){
Person.find({name: req.param('username')},function(err,person){
if(err)res.send(err);
res.json(person);
})
});

app.post('/user', function(req,res,next){
var aPerson = new Person({name: req.query.name});
aPerson.save(function(err){
if(err) res.send(err);
console.log('Person Saved !!!');
res.send('Person Saved !!!')
})
});

var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});





Casos de éxito
Linkedin
http://highscalability.com/blog/2012/10/4/linkedin-moved-from-rails-to-node-27-servers-cut-and-up-to-2.html


PayPal.
http://highscalability.com/blog/2013/12/11/using-nodejs-paypal-doubles-rps-lowers-latency-with-fewer-de.html

PayPal gives yet another glowing report of an app rewritten in node.js experiencing substantial performance improvements. PayPal rewrote their account overview page, one of the most trafficked apps on the website, which was previously written in King Java.

Yahoo - Mojito
https://developer.yahoo.com/cocktails/mojito/
https://github.com/yahoo/mojito/

Mojito is the JavaScript library implementing Cocktails, a JavaScript-based on-line/off-line, multi-device, hosted application platform.

Walmart. Mobile Applications
http://venturebeat.com/2012/01/24/why-walmart-is-using-node-js/

No es un caso de éxito pero está buenisimo. Da respuestas de preguntas negativas contra node
http://wintellect.com/blogs/dbanister/stop-fighting-node.js-in-the-enterprise

Yahoo, mozilla y google viendo node. Es una nota de como los grandes usan y tienen expectativas sobre nodejs
http://venturebeat.com/2012/01/24/node-at-google-mozilla-yahoo/

https://login.persona.org - Proyecto de mozilla en nodjs

Articulo mostrando empresas que usan node
http://www.nearform.com/nodecrunch/node-js-becoming-go-technology-enterprise#.U-4I7XWSw8o
Slides Casos de exitos con breve reseña del representante de cada empresa



Módulo 2

SISS
SISS es un servidor de aplicaciones desarrollado íntegramente en Node.js.
Nació de la necesidad de nuclear un grupo de soluciones REST para las aplicaciones del equipo Satélites.



Basicamente es una gran aplicacion que permitirá correr otras aplicaciones en forma controlada, interconectando señales y tareas. Unifica y establece patrones y protocolos de trabajo, como así también fuentes de datos en común.

Funciona en base a paquetes, los cuales pueden compartir recursos como librerías.
Cada paquete define su configuración en el archivo sisspack.js y una estructura de directorios.


Instalacion.
Para poder instalar y ejecutar SISS necesitamos contar con
- Redis (last version)
- Node.JS v 0.10.24 o superior
- MongoDB v2.4.9 o superior
- npm 1.3.21 o superior
- git 1.9.0 o superior

Una vez instalado el software necesario bajamos la ultima version estable de siss desde esta URL: http://lync.com.ar/download


SISSCore
El objeto SISSCore esta disponible en todo el ambiente SISS. Es una variable global con la instancia principal de SISS.
SISSCore nos aporta una serie de métodos importantes y comunes a todos los packages, libs, etc.

Metodos
on
El método on nos permite escuchar sobre un evento. Pasamos dos argumentos, el nombre del eventos y el callback del mismo.

emit
El método emit permite detonar un eventos. Pasamos como argumento el nombre del evento.

removeAllListeners
Elimina todos los listers de un evento (todos sus callbacks asociados).

fire
Es un alias de emit.

json
Envía al buffer de salida el object json que pasemos. Espera dos argumentos, el object a enviar y el object RES.

send
Envía el string que pasamos como primer argumento al object RES especificado en el segundo argumento.

render
Es el método encargado de hacer un render de una vista en el navegador. Espera 3 argumentos: la vista, la data y el object RES.

spooler
Almacena información en una collection de mongo asociada a un tid (transaction ID).
Espera 3 argumentos: data object, driver mongo, tid

request
Este método ejecuta un request hacia una url http o https.
Usa dos argumentos, el primero es un object con las options necesarias, el segundo es el callback.


Consola de administracion.
SISS cuenta con una consola de administracion que permite instalar paquetes, ver logs, ejecutar código remoto, etc.
La consola (SISS Console o SISSC) se comunica con SISS por medio de 2 canales de Redis dinámicos. los mismos son creados cuando SISS es iniciado y son informados por mensaje en pantalla.
Sin los dos tokens (los canales I/O) no podremos operar sobre SISS, así que es importante contar con ambos datos.






███████╗██╗███████╗███████╗ ██╗ ██╗ ██╗ ██████╗
██╔════╝██║██╔════╝██╔════╝ ██║ ██║ ███║ ╚════██╗
███████╗██║███████╗███████╗ ██║ ██║ ╚██║ █████╔╝
╚═══ ██║██║╚════██║╚════██║ ╚██╗ ██╔╝ ██║ ╚═══██╗
███████║██║███████║███████║ ╚████╔╝ ██║██╗██████╔╝
╚══════╝╚═╝╚══════╝╚══════╝ ╚═══╝ ╚═╝╚═╝╚═════╝

Exec: /home/lortmorris/repos/sissweb/siss1.2/start.js [ '-port', 1234 ]
Init SISS Instance: { '/usr/local/bin/node': '/home/lortmorris/repos/sissweb/siss1.2/start.js',
'-port': 1234 }
Debug mode: 0
Secret channel input: 0e871f6d05b6b4b0856bf478b5d5e9fb7aff7325
Secret channel output: 6683effba7712949e0efade15a780d5d9d948ad9
Init remote console
Primary domain lync.com.ar loaded!
Primary domain sissweb.localhost.com.ar loaded!
Running sissweb
Load lib: index
connect.multipart() will be removed in connect 3.0
visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives
connect.limit() will be removed in connect 3.0
loading routings: core
loading routings: web
______________FUSIONPATH_____________________
SISS listening on: 1234
app: function app(req, res, next){ app.handle(req, res, next); } appHTTPS: null

Ejecutamos sissconsole.js informando de los dos datos para la conexión.

server$ node sissconsole.js -input 0e871f6d05b6b4b0856bf478b5d5e9fb7aff7325 -output 6683effba7712949e0efade15a780d5d9d948ad9

Una vez dentro de la consola de SISS veremos un prompt como el siguiente:

SISS:/>

Para probar que realmente estemos conectados a SISS Server ejecutaremos el comando “show” con el argumento routes.
El comando show muestra información del servidor, el argumento routes indica que queremos ver todas las rutas mapeadas por SISS Server.

El comando show cuenta con los siguientes argumentos:
web: muestra los paquetes instalados y cargados del tipo web
api: muestra los paquetes instalados y cargados del tipo api
hardware: muestra información de cpu, memoria y red del servidor en donde esta corriendo SISS.

SISS:/>{ hostname: 'lortmorris-ninja',
arch: 'x64',
cpu:
[ { model: 'Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz',
speed: 800,
times: },
{ model: 'Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz',
speed: 1200,
times: },
{ model: 'Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz',
speed: 800,
times: },
{ model: 'Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz',
speed: 800,
times: } ],
memory: { total: 5902.95703125, free: 202.33167825223435 },
interfaces:
{ lo: [ , ],
eth0: [ , ],
wlan0: [ , ] },
os: 'linux' }



Download
http://lync.com.ar/guide
0
0
0
0No comments yet