L9: Práctica 4_1 - myTeachingURJC/2018-19-LTAW GitHub Wiki
- Tiempo: 2h
- Fecha: Lunes, 25-Marzo-2019
-
Objetivos de la sesión:
- Explicar el enunciado de la práctica 4
- Utilizar express
- Aprender a enviar mensajes entre cliente y servidor usando socket.io
Hacer un chat en el que múltiples usuarios puedan hablar entre sí. Primero hay que lanzar el servidor (hecho con node) al que se conectarán los usuarios. Cada vez que un usuario se conecte el servidor le enviará un mensaje de Bienvenida, y anunciará al resto de participantes que se ha conectado alguien nuevo
La conexión al servidor será a través del navegador. Una vez conectado el servidor devuelve la página html y los ficheros javascript y de estilo necesarios
El servidor, además, responderá a los comandos que empiezan por /. Los comandos implementados serán:
- /help: Mostrará una lista con todos los comandos soportados
- /list: Devolverá el número de usuarios conectados
- /hello: El servidor nos devolverá el saludo
- /date: Nos devolverá la fecha
Actividades guiadas por el profesor. Haremos lo siguiente:
Para implementar servidores web más fácilmente con node.js existen bibliotecas ya creadas, que nos hacen la vida mucho más fácil. Una de ellas es Express. Veremos un ejemplo de cómo ponerla en marcha
- Creamos un directorio de trabajo (por ejemplo test-express) y entramos en él
- Instalamos Express ejecutando el comando:
npm install express
- Creamos nuestro servidor web con express en el fichero test.js. Sólo tendrá el punto de entrada raiz (/). Este es el código
const express = require('express')
const app = express()
const http = require('http').Server(app);
//-- Puerto donde lanzar el servidor
const PORT = 3000
//-- Punto de entrada pricipal
app.get('/', (req, res) => {
res.send('Probando express... ¡¡¡qué fácil!!!')
})
//-- Lanzar servidor
http.listen(PORT, function(){
console.log('Servidor lanzado en puerto ' + PORT);
});
Este programa lanza el servidor web en el puerto 3000. Mediante app.get('/') configuramos la función de retrollamada para que se ejecute cada vez que un cliente se conecta a la página principal
Ejecutamos el programa:
$ node test.js
Servidor lanzado en puerto 3000
Ahora al conectarnos en el navegador a la URL localhost:3000 nos aparecerá lo siguiente
En esta animación lo vemos en acción. Si nos conectamos a un recurso no implementado, express nos informa
Añadir un nuevo punto de entrada es tan fácil como invocar la función app.get() pasándole como argumento el nombre del recurso. En este código hemos añadido el recurso /woala
const express = require('express')
const app = express()
const http = require('http').Server(app);
//-- Puerto donde lanzar el servidor
const PORT = 3000
//-- Punto de entrada pricipal
app.get('/', (req, res) => {
res.send('Probando express... ¡¡¡qué fácil!!!')
console.log("Acceso a /")
})
app.get('/woala', (req, res) => {
res.send('WOALA!!! Chuck norris approved!!! :-)')
console.log("Acceso a /woala")
})
//-- Lanzar servidor
http.listen(PORT, function(){
console.log('Servidor lanzado en puerto ' + PORT);
});
Lo ejecutamos de nuevo y desde el navegador nos conectamos localhost:3000/woala
En esta animación lo vemos en funcionamiento
Modificamos el punto de entrada pricipal para devolver un fichero html. El index.hmtl que usaremos es:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>MI CHAT</title>
</head>
<body">
<p>Plantilla para mi chat....</p>
<input id="msg" autocomplete="off"/>
<button type="button" id="send">SEND</button>
<p id="display"></p>
</body>
</html>
Y en el nuevo código sólo tenemos que invocar a res.sendFile() pasándole como argumento el nombre del fichero a devolver
const express = require('express')
const app = express()
const http = require('http').Server(app);
//-- Puerto donde lanzar el servidor
const PORT = 3000
//-- Punto de entrada pricipal
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
console.log("/index.html")
})
app.get('/woala', (req, res) => {
res.send('WOALA!!! Chuck norris approved!!! :-)')
console.log("Acceso a /woala")
})
//-- Lanzar servidor
http.listen(PORT, function(){
console.log('Servidor lanzado en puerto ' + PORT);
});
Ejecutamos el servidor y en el navegador veremos nuestra página html:
¡Listos para hacer nuestro chat!
Los websockets nos permite que haya una comunicación bidireccional entre clientes y servidores a través de HTTP. Gracias a bibliotecas como Socket.io es muy sencillo su implementación
La instalación es muy fácil. Sólo hay ejecutar el siguiente comando:
npm install socket.io
Además del servidor node, en el cliente se tiene que ejecutar otro programa javascript, que es el que se comunicará con el servidor. Comenzaremos con un fichero de cliente "Hola mundo", que simplemente imprime un mensaje en la consola para comprobar que se ha cargado correctamente. Será nuestro chat-client.js
function main() {
console.log("Hola!!!!")
}
Desde el index.html cargamos este javascript, y también la biblioteca de socket.io para el cliente
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>MI CHAT</title>
<script src="/socket.io/socket.io.js"></script>
<script src="chat-client.js"></script>
</head>
<body onload="main();">
<p>Plantilla para mi chat....</p>
<input id="msg" autocomplete="off" />
<button type="button" id="send">SEND</button>
<p id="display"></p>
</body>
</html>
Modificamos el servidor para que sirva el fichero chat-client.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//--Servir la pagina principal
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log("Página principal: /")
});
//-- Servir el cliente javascript
app.get('/chat-client.js', function(req, res){
res.sendFile(__dirname + '/chat-client.js');
console.log("Fichero js solicituado")
});
//-- Lanzar el servidor
http.listen(3000, function(){
console.log('listening on *:3000');
});
Ejecutamos el servidor y nos conectamos desde el navegador. Si abrimos la consola de Firefox veremos el mensaje "Hola!!!" que ha escrito nuestro cliente. Se ha transferido correctamente desde el servidor y se ha ejecutado. ¡Estamos listos para probar la biblioteca socket.io!
En el fichero cliente simplemente creamos un objeto io:
function main() {
console.log("Hola!!!!")
//-- Crear un socket.io. Se establece la conexion
//-- con el servidor
var socket = io();
}
Y en el servidor se recibirá el evento connection cada vez que se conecte un usuario. Lo capturamos con la función io.on(). Simplemente lo notificamos en la consola para comprobarlo
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//--Servir la pagina principal
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log("Página principal: /")
});
//-- Servir el cliente javascript
app.get('/chat-client.js', function(req, res){
res.sendFile(__dirname + '/chat-client.js');
console.log("Fichero js solicituado")
});
//-- Lanzar el servidor
http.listen(3000, function(){
console.log('listening on *:3000');
});
//-- Evento: Nueva conexion recibida
//-- Un nuevo cliente se ha conectado!
io.on('connection', function(socket){
console.log('--> Usuario conectado!');
});
Lo ejecutamos. Veremos que nos aparece el mensaje en la consola del servidor. Si abrimos varias pestañas, nos aparecerán notificaciones por cada una nueva abierta
La desconexión la detectamos con el evento "disconnect". Una vez que la conexión está establecida, si se recibe el evento de desconexion lo notificaremos en la consola. El nuevo servidor es el siguiente:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//--Servir la pagina principal
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log("Página principal: /")
});
//-- Servir el cliente javascript
app.get('/chat-client.js', function(req, res){
res.sendFile(__dirname + '/chat-client.js');
console.log("Fichero js solicituado")
});
//-- Lanzar el servidor
http.listen(3000, function(){
console.log('listening on *:3000');
});
//-- Evento: Nueva conexion recibida
//-- Un nuevo cliente se ha conectado!
io.on('connection', function(socket){
console.log('--> Usuario conectado!');
//-- Detectar si el usuario se ha desconectado
socket.on('disconnect', function(){
console.log('--> Usuario Desconectado');
});
});
Y en esta animación se muestra su funcionamiento. Al cerrar las pestañas se detecta la desconexión
Para enviar un mensaje al servidor hay que llamar al método socket.emit(), pasándo como argumento el nombre del evento (usaremos por ejemplo "new_message") y el mensaje a enviar
En el cliente, cada vez que apretemos el botón de SEND se emitirá el mensaje y se mostrará en la consola el texto "Mensaje emitido"
function main() {
console.log("Hola!!!!-------------")
//-- Crear el websocket
var socket = io();
//-- Obtener los elementos de interfaz:
//-- Boton de envio de mensaje
var send = document.getElementById('send')
//-- Parrafo para mostrar mensajes recibidos
var display = document.getElementById('display')
//-- Caja con el mensaje a enviar
var msg = document.getElementById("msg")
//-- Cuando se aprieta el botón de enviar...
send.onclick = () => {
//-- Enviar el mensaje, con el evento "new_message"
socket.emit('new_message', msg.value);
//-- Lo notificamos en la consola del navegador
console.log("Mensaje emitido")
}
}
El servidor estará atento al evento "new_message". Cuando se produzca, recibirá el mensaje y lo mostrará en la consola. El código queda así:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//--Servir la pagina principal
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log("Página principal2: /")
});
//-- Servir el cliente javascript
app.get('/chat-client.js', function(req, res){
res.sendFile(__dirname + '/chat-client.js');
console.log("Fichero js solicituado")
});
//-- Lanzar el servidor
http.listen(3000, function(){
console.log('listening on *:3000');
});
//-- Evento: Nueva conexion recibida
//-- Un nuevo cliente se ha conectado!
io.on('connection', function(socket){
console.log('--> Usuario conectado!');
//-- Detectar si el usuario se ha desconectado
socket.on('disconnect', function(){
console.log('--> Usuario Desconectado');
});
//-- Detectar si se ha recibido un mensaje del cliente
socket.on('new_message', msg => {
//-- Notificarlo en la consola del servidor
console.log("Mensaje recibido: " + msg)
});
});
En esta animación se muestra su funcionamiento
Por último, cada vez que el servidor reciba un mensaje de algún cliente, lo emitirá a todos (incluido el que lo envió). En los clientes cada vez que se reciba un mensaje se mostrará:
function main() {
console.log("Hola!!!!-------------")
//-- Crear el websocket
var socket = io();
//-- Obtener los elementos de interfaz:
//-- Boton de envio de mensaje
var send = document.getElementById('send')
//-- Parrafo para mostrar mensajes recibidos
var display = document.getElementById('display')
//-- Caja con el mensaje a enviar
var msg = document.getElementById("msg")
//-- Cuando se aprieta el botón de enviar...
send.onclick = () => {
//-- Enviar el mensaje, con el evento "new_message"
socket.emit('new_message', msg.value);
//-- Lo notificamos en la consola del navegador
console.log("Mensaje emitido")
}
//-- Cuando se reciba un mensaje del servidor se muestra
//-- en el párrafo
socket.on('new_message', msg => {
display.innerHTML = msg;
});
}
Este es el código del servidor:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//--Servir la pagina principal
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log("Página principal: /")
});
//-- Servir el cliente javascript
app.get('/chat-client.js', function(req, res){
res.sendFile(__dirname + '/chat-client.js');
console.log("Fichero js solicituado")
});
//-- Lanzar el servidor
http.listen(3000, function(){
console.log('listening on *:3000');
});
//-- Evento: Nueva conexion recibida
//-- Un nuevo cliente se ha conectado!
io.on('connection', function(socket){
console.log('--> Usuario conectado!');
//-- Detectar si el usuario se ha desconectado
socket.on('disconnect', function(){
console.log('--> Usuario Desconectado');
});
//-- Detectar si se ha recibido un mensaje del cliente
socket.on('new_message', msg => {
//-- Notificarlo en la consola del servidor
console.log("Mensaje recibido: " + msg)
//-- Emitir un mensaje a todos los clientes conectados
io.emit('new_message', msg);
})
});
En este pantallazo se muestra el resultado de enviar mensajes desde diferentes clientes
Y en esta animación se puede ver en funcionamiento:
- Comenzar con la práctica 4
- Jose María Cañas
- Juan González-Gómez (Obijuan)