Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Ap Sist Escalables On PDF
Ap Sist Escalables On PDF
• *Node.js
• *Socket.IO
• *Express
• *Redis
• *Crypto (módulo para encriptación)
• *Ejs (motor de plantillas)
• *Session.socket.io (módulo para manejo de sesiones en Socket.IO)
www.redusers.com
SISTEMAS WEB ESCALABLES 3
www.redusers.com
4 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
express –e SocialRedis
cd SocialRedis && npm install
npm install redis
npm install crypto
npm install socket.io
npm install session.socket.io
nodemon app.js
Express provee una extensa lista de ejemplos que cubren todos los aspectos del framework, como auten-
ticación, manejo de plantillas, cookies, solución de errores, parámetros de entrada y administración de
sesiones, entre otros. Podemos acceder a los ejemplos en la siguiente dirección: https://github.com/
visionmedia/express/tree/master/examples.
www.redusers.com
SISTEMAS WEB ESCALABLES 5
// definicion de modulos
var express = require(‘express’)
, routes = require(‘./routes’)
, user = require(‘./routes/user’)
, http = require(‘http’)
, path = require(‘path’)
, redis = require(‘redis’)
, crypto = require(‘crypto’)
, ssio = require(‘session.socket.io’);
// inicializacion de variables
var app = express()
, server = http.createServer(app)
, io = require(‘socket.io’).listen(server)
, sessionStore = new express.session.MemoryStore()
, cookieParser = express.cookieParser(‘!@#$%^&*()1234567890qwerty’)
, sessionIO = new ssio(io, sessionStore, cookieParser);
SELECCIONAR UN FRAMEWORK
Actualmente los desarrolladores nos encontramos con una gran cantidad de frameworks MVC para organizar y
estructurar las aplicaciones en JS. Para ayudarnos a resolver el problema existe un proyecto llamado TodoMVC,
el cual ofrece una funcionalidad similar para varios frameworks como Backbone, Ember o AngularJS.
www.redusers.com
6 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// middlewares de Express
app.use(express.favicon());
app.use(express.logger(‘dev’));
app.use(express.bodyParser());
app.use(cookieParser);
app.use(express.session({ store: sessionStore }));
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, ‘public’)));
www.redusers.com
SISTEMAS WEB ESCALABLES 7
www.redusers.com
8 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// listen
server.listen(app.get(‘port’), function(){
console.log(‘Express server listening on port ‘ + app.get(‘port’));
});
input[type=”text”],
www.redusers.com
SISTEMAS WEB ESCALABLES 9
nav ul li{border: 1px solid transparent; cursor: pointer; font-size: 15px; height:
100%; line-height: 46px; padding: 0; width: auto;}
.marco.blanco{background-color: #FFFFFF;}
.marco.gris{background-color: #F8F8F8;}
.marco.celeste{background-color: #BAD9F1;}
.login{float: right; padding: 5px 15px; text-align: right; width: 401px; font-size:
15px;}
www.redusers.com
10 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 11
.usuariosLista{min-height: 400px;}
.bloque .header img{margin-right: 10px; float: left; width: 30px; height: 30px;}
#postFrm{width: 436px;}
www.redusers.com
12 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
<!DOCTYPE html>
<html lang=”es”>
<head>
<meta charset=”utf-8” />
<title><%= titulo %></title>
<link rel=”stylesheet” href=”/css/style.css” />
<link rel=”shortcut icon” href=”/img/favicon.png” >
</head>
<body>
<div class=”contenedor”>
<footer>
<p>
<b><%= titulo %></b> - <%= autor %>
</p>
</footer>
</div>
<script type=”text/javascript” src=”/socket.io/socket.io.js”></script>
<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jque-
ry/1.9.0/jquery.min.js”></script>
<script type=”text/javascript” src=”/js/script.js”></script>
www.redusers.com
SISTEMAS WEB ESCALABLES 13
<header>
<h1><%= titulo %></h1>
<!-- formulario de login -->
<div class=”login marco blanco”>
<form id=”loginFrm” action=””>
<input type=”text” name=”usuario” value=”” placeholder=”Usuario”/>
<input type=”password” name=”clave” value=”” placeholder=”Clave”/>
<input type=”submit” id=”loginBtn” value=”Entrar” />
</form>
</div>
Como hemos visto, Express ofrece un entorno en el cual podemos, entre otras cosas, manejar el ruteo,
y con Node es posible crear nuestro propio servidor web. Una interesante propuesta es desarrollar el
mismo sistema utilizando PHP y Apache para identificar las ventajas y desventajas de cada uno y definir
cuándo utilizar una arquitectura u otra.
www.redusers.com
14 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
</header>
<!-- logos de Redis y Node -->
<section class=”tecnologias”>
<img src=”img/bg_redis.png” alt=”Redis”/>
<img src=”img/bg_nodejs.png” alt=”Node.js”/>
</section>
<!-- formulario de registro -->
<section class=”columna_derecha”>
<article class=”registro marco blanco”>
<h2>Usuario Nuevo:</h2>
<div>
<form id=”nuevoFrm” action=””>
<input type=”text” name=”nombre” value=”” placeholder=”Nombre” />
<input type=”text” name=”apellido” value=”” placeholder=”Apellido” />
<input type=”text” name=”usuario” value=”” placeholder=”Usuario” />
<input type=”password” name=”clave” value=”” placeholder=”Clave” />
<input type=”text” name=”correo” value=”” placeholder=”Correo” />
<input type=”submit” id=”nuevoBtn” value=”Registrar” />
</form>
</div>
</article>
<!-- elemento para mostrar los usuarios registrados -->
<aside class=”usuarios_registrados marco blanco”>
<p>Ya se registraron <span id=”totalUsuarios”>0</span> usuarios</p>
</aside>
</section>
<!-- inluimos el archivo footer.ejs -->
<% include footer %>
www.redusers.com
SISTEMAS WEB ESCALABLES 15
Siempre es buena idea formar parte de los grupos de usuarios de las tecnologías que nos interesan.
Express posee una lista que actualmente cuenta con alrededor de dos mil usuarios, discutiendo cerca de
cinco mil temas. El grupo utiliza la plataforma Google Groups y podemos unirnos a través del siguiente
enlace: https://groups.google.com/forum/#!forum/express-js.
www.redusers.com
16 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
$(document).ready(function(){
// registro de usuario
$(document).on(‘submit’, ‘#nuevoFrm’, function(e){
e.preventDefault();
setUsuario($(this));
});
});
www.redusers.com
SISTEMAS WEB ESCALABLES 17
//app.post(‘/registro’, user.registro);
a esto:
app.post(‘/registro’, user.registro);
www.redusers.com
18 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// registramos el usuario
exports.registro = function(req, res) {
www.redusers.com
SISTEMAS WEB ESCALABLES 19
www.redusers.com
20 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 21
// login
$(document).on(‘submit’, ‘#loginFrm’, function(e){
e.preventDefault();
login($(this));
});
Redis provee una vía para testear, agregar y mejorar características de la base de datos: solo es necesa-
rio clonar el repositorio oficial de Github. Otra alternativa para contribuir con Redis es reportar bugs o re-
solver los existentes. Ambas opciones son definidas en detalle en el enlace http://redis.io/community.
www.redusers.com
22 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
//app.post(‘/login’, user.login);
a esto:
app.post(‘/login’, user.login);
www.redusers.com
SISTEMAS WEB ESCALABLES 23
www.redusers.com
24 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 25
<header>
<h1><%= titulo %></h1>
<!-- formulario de busqeda -->
<div id=”buscador”>
<input type=”text” id=”tBuscar” placeholder=”Buscar...” class=”marco” />
<input type=”submit” id=”bBuscar” value=”Buscar” />
</div>
www.redusers.com
26 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
</div>
</aside>
www.redusers.com
SISTEMAS WEB ESCALABLES 27
www.redusers.com
28 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
usrEnLinea[session.usr.uid] = socket.id;
usuarios.forEach(function(id){
// verificamos que no sea el usuario actual
if (uid != id){
// verificamos que no tenga una solicitud pendiente
db.sismember(‘uid:’ + id + ‘:solicitudes’, uid, function (err, solicitudEnviada)
{
if(solicitudEnviada == 0){
// obtenemos la informacion del usuario
db.hgetall(‘uid:’ + id, function (err, usuario) {
usrNuevos.push({‘uid’: id,
www.redusers.com
SISTEMAS WEB ESCALABLES 29
‘nombre’ : usuario.nombre,
‘apellido’ : usuario.apellido
});
// emitimos los usuarios
if (usrNuevos.length == usuarios.length - 1)
io.sockets.socket(usrEnLinea[uid]).emit(‘setUsuariosNuevos’, usr-
Nuevos);
});
}
});
}
});
}
});
}
exports.getUsuariosNuevos = getUsuariosNuevos;
Ahora necesitamos capturar el evento del lado del cliente. Para esto,
agregamos lo siguiente al método $(document).ready() del archivo script.js:
www.redusers.com
30 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 31
Por defecto, Express usa el motor de plantillas Jade, el cual es muy bueno pero abstrae de una manera
significante la utilización de elementos HTML. Una alternativa es utilizar EJS, más amigable y simple al
crear estructuras complejas. Para instalarlo cuando creamos una aplicación, debemos escribir el siguien-
te comando: express -e nombreDeLaApp.
www.redusers.com
32 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
//app.post(‘/setSolicitud’, user.setSolicitud);
a esto:
app.post(‘/setSolicitud’, user.setSolicitud);
www.redusers.com
SISTEMAS WEB ESCALABLES 33
www.redusers.com
34 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
exports.getSolicitudes = getSolicitudes;
DOCUMENTACIÓN DE EXPRESS 2X
Si bien actualmente Express se encuentra en la versión 3, debido a que se han creado miles de apli-
caciones con la versión 2 fue necesario dejar la documentación accesible para consultas de desarro-
lladores que necesitan mantener sistemas escritos con esta versión. Para ver la documentación corres-
pondiente a Express en su versión 2, deberemos acceder a la página que se encuentra en la dirección
http://expressjs.com/2x.
www.redusers.com
SISTEMAS WEB ESCALABLES 35
$(‘#solicitudes’).prepend(contenido);
});
$(‘#valorContador’).fadeOut(500, function() {
$(this).html(solicitudes.length).fadeIn(500)
});
}
}
www.redusers.com
36 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// contador de solicitudes
$(document).on(‘click’, ‘.contador’, function(){
$(‘#solicitudes’).fadeToggle(500);
});
Sockt.IO es una librería en lenguaje JavaScript, pero también es posible utilizar otras versiones, escri-
tas en diferentes lenguajes, como Java, Objective-C, C, C++, Go, Python y PHP, entre otros. Esto es,
sin duda, una gran ventaja, ya que es posible desarrollar sistemas basados en lenguajes como PHP en
tiempo real. Podemos ver la lista en https://github.com/learnboost/socket.io/wiki.
www.redusers.com
SISTEMAS WEB ESCALABLES 37
Con este código, cada vez que se conecta, el usuario puede obtener
el listado de las solicitudes pendientes.
En el repositorio oficial de Socket.IO hay una lista con varios sistemas que pueden servirnos como base
para el desarrollo de algún proyecto en tiempo real. Un ejemplo muy útil es collabshot, una herramienta
colaborativa de edición de imágenes, notas y chat. Podemos acceder a la lista de proyectos a través
del siguiente enlace: https://github.com/LearnBoost/Socket.IO/wiki/Projects-using-Socket.IO.
www.redusers.com
38 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
$(‘#valorContador’).fadeOut(500, function() {
$(this).html(parseInt($(this).html()) - 1).fadeIn(500)
});
}else
$(‘#solicitudes li[uid=”’ + boton.attr(‘uid’) + ‘”]’).html(respuesta.mensaje);
}
);
}
www.redusers.com
SISTEMAS WEB ESCALABLES 39
//app.post(‘/setRespuestaSolicitud’, user.setRespuestaSolicitud);
app.post(‘/setRespuestaSolicitud’, user.setRespuestaSolicitud);
www.redusers.com
40 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 41
amigos.forEach(function(id){
i++;
// verificamos que el usuario se encuentre conectado
if (usrEnLinea[id]){
// obtenemos la informacion del usuario
db.hgetall(‘uid:’ + id, function (err, usuario) {
usrConectados.push({‘uid’: id,
‘nombre’ : usuario.nombre,
‘apellido’ : usuario.apellido
});
Fred Sarmento ha creado un portal con recursos para los frontend, donde se incluyen librerías y plugins
como jQuery, Normalize.css, herramientas de debug y testeo como Firebug y Chrome Developer Tools,
tutoriales en línea, y editores de código como Sublime Text3. Podemos ver la lista completa en el siguien-
te enlace: http://fredsarmento.me/frontend-tools.
www.redusers.com
42 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
exports.getAmigosConectados = getAmigosConectados;
Vamos a capturar este evento del lado del cliente, definiendo lo que
sigue en el archivo script.js dentro del método $(document).ready():
www.redusers.com
SISTEMAS WEB ESCALABLES 43
Informar cuando
se conecta un usuario
Vamos a crear una función para informar a los amigos, en tiempo
real, que un usuario se ha conectado. Primero nos encargamos de
agregar el siguiente código en el archivo denominado index.js, en la
función sessionIO.on(), dentro del condicional de sesión:
INTERNET
Según los últimos informes de Cisco, para el año 2017 habrá cerca de 3.600 millones de usuarios de
Internet, esto se puede resumir como casi el 50% de la población mundial. Implicaría un aumento del
tráfico mundial por tres, donde el servicio será accesible desde notebooks, netbooks, smartphones,
tablets y televisores inteligentes.
www.redusers.com
44 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
exports.setAmigoConectado = setAmigoConectado;
www.redusers.com
SISTEMAS WEB ESCALABLES 45
}
}
Informar cuando
se desconecta un usuario
Vamos a crear una función para informar a los amigos cuando un
usuario se desconecta. Si observamos home.ejs veremos que hemos
definido el enlace salir y apunta a la ruta /salir. Para que nuestro sistema
pueda efectuar alguna acción cuando recibe esta ruta, necesitaremos
descomentar la siguiente línea del archivo app.js, pasando de esto:
//app.get(‘/salir’, user.logout);
a esto:
app.get(‘/salir’, user.logout);
www.redusers.com
46 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// logout
exports.logout = function(req, res){
// informamos a los amigos que se ha desconectado el usuario
setAmigoDesconectado(req.session.usr.uid);
// eliminamos el uid del array de usuarios y la session
delete usrEnLinea[req.session.usr.uid];
// eliminamos la clave se session
req.session.usr = ‘’;
// redireccionamos
res.redirect(‘/’);
}
www.redusers.com
SISTEMAS WEB ESCALABLES 47
Aquí hemos obtenido todos los amigos del usuario y, para cada uno
de ellos, hemos verificado si estaba conectado, emitiendo el evento
setAmigoDesconectado con el uid del usuario actual.
Para continuar nos encargamos de exportar la función para que esté
disponible desde cualquier lugar del sistema:
exports.setAmigoDesconectado = setAmigoDesconectado;
www.redusers.com
48 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 49
$(‘.chat’).append(ventana);
}
}
Además de las herramientas que vienen integradas por defecto en Express, integrantes de la comunidad
oficial han creado decenas de extensiones muy útiles para ser utilizadas en los desarrollos y ahorrar
tiempo de programación. Podemos conocerlas accediendo al siguiente enlace: https://github.com/
senchalabs/connect/wiki.
www.redusers.com
50 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
// emitimos el mensaje
sockets.emit(‘enviarMensaje’, data);
// agregamos el mensaje al textarea
$(‘#ventana-’+ uid +’ textarea’).val($(‘#ventana-’+ uid +’ textarea’).val() + ‘yo:
‘ + msg + ‘\r\n’);
// limpiamos la caja de texto
$(‘#ventana-’+ uid +’ .chat-text’).val(‘’);
}
www.redusers.com
SISTEMAS WEB ESCALABLES 51
exports.enviarMensaje = enviarMensaje;
var ultimaFechaMsg = 0;
www.redusers.com
52 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
StatCounter es un sitio que publica estadísticas globales acerca de diferentes tecnologías. Entre las opcio-
nes que ofrece se encuentra la posibilidad de ver qué tecnología comparar, permite seleccionar el tipo de
gráfico (líneas, barras o mapa) y además permite descargar el gráfico en formato JPG o CSV. Podemos
conocerlo mejor a través del siguiente enlace: http://gs.statcounter.com.
www.redusers.com
SISTEMAS WEB ESCALABLES 53
// nuevo post
$(document).on(‘submit’, ‘#postFrm’, function(e){
e.preventDefault();
setPost($(this));
});
www.redusers.com
54 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
$(‘#posts’).prepend(bloque);
$(‘#postFrm textarea’).val(‘’);
}else
mostrarMensajeFormulario(form, respuesta.mensaje);
}
);
}
//app.post(‘/setPost’, user.setPost);
app.post(‘/setPost’, user.setPost);
www.redusers.com
SISTEMAS WEB ESCALABLES 55
www.redusers.com
56 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 57
www.redusers.com
58 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
Hemos obtenido los últimos diez posts del usuario actual y, de cada
uno de ellos, la información completa y del usuario que la escribió, que
almacenamos en un array. Por último, debemos realizar la emisión del
evento llamado setPosts con el array creado.
A continuación debemos capturar el evento setPosts del lado del
cliente. Para realizar esto agregaremos lo que sigue en el archivo
script.js en el método $(document).ready():
$(‘#posts’).append(bloque);
});
};
}
www.redusers.com
SISTEMAS WEB ESCALABLES 59
www.redusers.com
60 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
www.redusers.com
SISTEMAS WEB ESCALABLES 61
RESUMEN
Hemos aplicado todos los conocimientos y temas tratados a lo largo del libro mediante el desarrollo de
una red social que propone un gran cambio en la manera de pensar las acciones, ya que la mayoría de las
interacciones deben ser reflejadas en tiempo real y desencadenan un efecto en los demás usuarios. Las
bases de datos NoSQL, como Redis, cuentan con ventaja en la disponibilidad para grandes volúmenes
de datos, ofreciendo un gran desempeño en el funcionamiento de cualquier sistema; al mismo tiempo,
mediante Socket.IO es posible emitir y recibir eventos completamente personalizados, que entregan un
aspecto único a la interacción de los usuarios con los sistemas.
www.redusers.com
62 APÉNDICE. DESARROLLO DE UNA RED SOCIAL
Actividades
TEST DE AUTOEVALUACIÓN
3 ¿Con qué característica debe contar una variable para tener un alcance global?
4 ¿ Qué característica debe tener una función para tener un alcance global?
10 ¿Un sistema desarrollado con Node y Express necesita de un servidor web como
Apache?
EJERCICIOS PRÁCTICOS
3 Genere la función Ver y editar el perfil actual y Acceder al perfil de los amigos.
PROFESOR EN LÍNEA
www.redusers.com