Práctica 3: Websockets - Sianats/LTAW-Practicas GitHub Wiki

Práctica 3: Chat con Websockets

Índice

Introducción

En esta práctica habrá que hacer una aplicación Web de Chat, en el que múltiples usuarios puedan hablar entre sí a través del Navegador. La aplicación consiste en un programa servidor hecho en node.js, al que se conectan los clientes desde los navegadores. Cada vez que un usuario se conecte al servidor se le enviará un mensaje de bienvenida, que sólo él verá, y aunciará al resto de participantes que se ha conectado alguien nuevo.

Para el intercambio de datos entre los clientes y el servidor se utilizará la biblioteca socket.io. Además, la aplicación web se desarrollará utilizando el paquete express de Node.

Documentación técnica:

Mi código de esta práctica se encuentra en mi Repositorio 3. Una vez en este, seleccionaremos el contenido de la carpeta public y el archivo server.js.

Front-end

Tanto en los css como en el html, hay especificaciones de qué hace cada cosa. Por lo que solo me queda enseñar el resultado estético. Una vez en el servidor, mi chat tiene esta apariencia (inspirada en la red social WhatsApp):

Puedes personalizarlo un poco más, introduciendo un usuario (si no lo especificas, tu user se llamará Anónimo por defecto):

Y cuando se vaya alguien del chat, también te saltará un aviso. Quedaría con la siguiente forma: ![](https://github.com/Sianats/LTAW-Practicas/blob/main/P0/wiki/P3/3.png)

Back-end

Adjunto mi código, con sus funciones explicadas una a una en los comentarios del propio:

  • Código del archivo Client.js:
//Establezco constantes que, gracias a su identificador, podré usar en mi archivo html
const display = document.getElementById("display");
const msg_entry = document.getElementById("msg_entry");
const usuario = document.getElementById("user");
const x = document.getElementById("us");
const userestablecido = document.getElementById("userestablecido");

//Declaro que el usuario se llamará 'Anónimo' siempre que no establezca otro nombre
let User = "Anónimo";
// Pongo la notificación de escribiendo en falso, por defecto.
let escribiendo = false;
const socket = io();
// Declaro el audio que voy a usar de tono de notificación
let notif = new Audio('notificacion.mp3');

//Creo esta función que servirá para la estructura de los mensajes y que se vean en pantalla
socket.on("message", (msg)=>{
  //Declaro que si el mensaje no incluye ese texto específico, la estructura sea así
  if(!msg.includes(' se ha unido</h5>')){
  display.innerHTML += '<p class="mess mess-r" style="text-align: right";>' + msg + '</p>';
  } else {
    // Si aparece ese mensaje en el texto, no declaro ninguna clase o estilo definido
    //(es puramente estético. Solo es css, no tiene funcionalidad js).
    display.innerHTML += '<p>' + msg + '</p>';
  }
});


// Si se detectan cambios en la entrada de texto (escribir), el valor
// de mi variable 'escribiendo' se pone en verdadero y salta la notificación
msg_entry.oninput = () => {
  if(!escribiendo){
    escribiendo = true;
    // Te avisa de que el usuario establecido está escribiendo
    socket.send(User + ' esta escribiendo...');
  };
};

// Al apretar el botón enter, se envía un mensaje al servidor 
// y aparece en nuestro display
msg_entry.onchange = () => {
  if (msg_entry.value)
    socket.send(User + ": <br>" + msg_entry.value);
    escribiendo = false;
  //-- Borrar el mensaje actual
  msg_entry.value = "";
  // Suena el sonido de notifiación
  notif.play();
}

// Al cambiar el valor usuario...
usuario.onchange = () => {
    if (usuario.value )
    // el usuario pasa a llamarse como lo has declarado tu
    User = usuario.value;
    console.log("nombre usuario"+ usuario.value);
    // Desaparece el display que te permite cambiar el nombre
    document.getElementById("user").style.display = "none";
    document.getElementById("us").style.display = "none";
    // Te confirma que has cambiado el usuario y te imprime el que has establecido
    userestablecido.innerHTML = "Nombre de usuario:"+ ' ' + User; 
    // Manda un mensaje al chat avisando de que te has unido
    socket.send('<h5 style="text-align: center">' + User + ' se ha unido</h5>');
}
  • Código del archivo server.js:
//-- Cargar las dependencias
const socketServer = require('socket.io').Server;
const http = require('http');
const express = require('express');
const colors = require('colors');

const PUERTO = 9090;

//-- Crear una nueva aplciacion web
const app = express();

//-- Crear un servidor, asosiaco a la App de express
const server = http.Server(app);

//-- Crear el servidor de websockets, asociado al servidor http
const io = new socketServer(server);

//-------- PUNTOS DE ENTRADA DE LA APLICACION WEB
//-- Definir el punto de entrada principal de mi aplicación web
app.get('/', (req, res) => {
  let path = __dirname + '/public/chat.html';
  res.sendFile(path);
});

//-- Esto es necesario para que el servidor le envíe al cliente la
//-- biblioteca socket.io para el cliente
app.use('/', express.static(__dirname +'/'));

//-- El directorio publico contiene ficheros estáticos
app.use(express.static('public'));

//Establezco un valor predeterminado para la variable num
let num = 0;

//------------------- GESTION SOCKETS IO
//-- Evento: Nueva conexion recibida
io.on('connect', (socket) => {
  console.log('** NUEVA CONEXIÓN **'.yellow);
  // Mensaje de bienvenida al chat
  socket.write('¡Bienvenido al chat de ISAM!');
  // El numero de usuarios aumenta 1 cada vez que alguien se conecta
  num += 1;
  //-- Evento de desconexión
  socket.on('disconnect', function(){
    console.log('** CONEXIÓN TERMINADA **'.yellow);
    //Mensaje a los demás usuarios informando de que alguién abandonó el chat
    io.send('Un usuario ha abandonado el chat');
    // El número de usuarios en el servidor disminuye 1
    num -= 1;
  });  

  //-- Mensaje recibido: Reenviarlo a todos los clientes conectados
  socket.on("message", (msg)=> {
    // Establezco ifs que determinan que si el mensaje incluye ese comando y no la frase ' se ha unido</h5>',
    // entonces hará una cosa u otra dependiendo del comando que le pides
    if (msg.includes('/help') && !msg.includes(' se ha unido</h5>')){
      // imprime una lista de comandos a usar y sus funciones
      socket.write('Los comandos disponibles son: <br> <strong>/help:</strong> Este mismo :) <br> <strong>/list:</strong> Devolverá el número de usuarios conectados <br> <strong>/hello:</strong> El servidor nos devolverá el saludo <br> <strong>/date:</strong> Nos devolverá la fecha');
    }else if(msg.includes('/hello') && !msg.includes(' se ha unido</h5>')){
      // Te saluda
      socket.write('¡Hola! Mucho ánimo con la carrera :)');
    }else if(msg.includes('/list') && !msg.includes(' se ha unido</h5>')){
      // Te dice el número total de usuarios conectados al servidor
      socket.write('Hay un total de ' + num + ' usuarios conectados');
    }else if(msg.includes('/date') && !msg.includes(' se ha unido</h5>')){
      // Establece la fecha
      const tiempoTranscurrido = Date.now();
      const hoy = new Date(tiempoTranscurrido);
      // Imprime la fecha, específicamente la de España, en el formato Español
      socket.write('Hoy es: ' + hoy.toLocaleString('es-ES'));
    }else if(msg.includes('/' + '') && !msg.includes(' se ha unido</h5>') && !msg.includes('/date') && !msg.includes('/list') && !msg.includes('/help') && !msg.includes('/hello') ){
      // Si usas un comando no establecido, te salta un error con el siguiente mensaje:
      socket.write('Lo siento pero no es un comando válido :(');
    }else{
      // Si lo escrito no es un comando, se imprime en el chat y en el terminal el mensaje que has escrito
        console.log("Mensaje Recibido!: " + msg.blue);
        //-- Reenviarlo a todos los clientes conectados
        io.send(msg);
    }

  });

});

//-- Lanzar el servidor HTTP
//-- ¡Que empiecen los juegos de los WebSockets!
server.listen(PUERTO);
console.log("Escuchando en puerto: " + PUERTO);

Manual de usuario

Una vez descargado el repositorio y abierto en nuestro editor de código, hay que instalar los siguientes paquetes, introduciendo los siguientes comandos en el terminal integrado de la carpeta:

  • npm i websocket
  • npm i socket.io
  • npm i express
  • npm i colors

Asegurate de tener primero instalado Node.js en tu ordenador, sino no funcionará. Una vez todo instalado, escribe en el terminal el comando:

node server.js

Después, ves a tu navegador e introduce la URL: localhost:9090. ¡Ahora ya estás dentro de mi chat! usa el comando /help para ver los comandos disponibles y su uso, habla con más gente conectada al servidor, establece un nombre de usuario...

¡Recuerda! Tanto para mandar un mensaje como para establecer el usuario, solo tienes que pulsar la tecla enter

Mejoras

  • Incorporación de mensaje de notificación
  • Personalización de nombre de usuario
  • Notificación cuando alguien está escribiendo

Autores

Licencia

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