L9: Práctica 4_1 - myTeachingURJC/2018-19-LTAW GitHub Wiki

Sesión Laboratorio 9: Práctica 4-1

  • 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

Contenido

Enunciado Práctica 4

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

Actividades guiadas por el profesor. Haremos lo siguiente:

Express

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ñadiendo un nuevo punto de entrada

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

Devolviendo el fichero index.html

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!

Socket.io

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

Instalación

La instalación es muy fácil. Sólo hay ejecutar el siguiente comando:

npm install socket.io

Puesta en marcha

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!

Detectando la conexión de un cliente

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

Detectando la desconexión del cliente

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

Enviando mensajes al servidor

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

Recibiendo mensajes del servidor

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:

Actividades NO guiadas

  • Comenzar con la práctica 4

Autores

Licencia

Enlaces

⚠️ **GitHub.com Fallback** ⚠️