Práctica 3: Websockets - Sianats/LTAW-Practicas GitHub Wiki
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.
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.
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: 
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);
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
- Incorporación de mensaje de notificación
- Personalización de nombre de usuario
- Notificación cuando alguien está escribiendo