Los WebSocket fueron introducidos recientemente con la llegada de HTML5 y es sin duda una de las mejoras más esperadas. Los WebSockets nos permite trabajar de forma bidireccional entre el navegador y el servidor, permitiendo enviar y recibir mensajes de forma simultánea (Full Duplex) y manteniendo siempre una conexión activa con el servidor mediante Sockets TCP.
A pesar de que la WebSocket fue agregado como una nueva característica de HTML5, la verdad es que es inútil sin una implementación de WebSocket del lado del servidor y es aquí donde entra los lenguajes de programación.
Cómo funcionan los WebSockets
Como ya mencionamos anteriormente, los WebSocket trabajan mediante conexiones TCP con el servidor, por lo que permite mantener una conexión activa y bidireccional entre el Servidor y el Navegador. Para que una conexión WebSocket se dé, debemos de tener dos partes, un WebSocket Server y un WebSocket Cliente, El Server es aquel que acepta las conexiones y que representa el BackEnd y el cliente en este caso sería el navegador. En este contexto, el cliente es el que establece inicialmente la conexión con el servidor. Una vez establecida la conexión, tanto el servidor como el cliente se podrá enviar mensajes simultáneamente. Veamos la siguiente imagen:
En la imagen podemos apreciar que el Navegador (WebSocket Client) establece una conexión con el Server (WebSocket Server), el servidor acepta la conexión y a continuación inicia un intercambio de mensajes entre el Servidor y el Navegador. Cabe mencionar que los WebSocket mantiene su conexión activa durante todo el tiempo que tengamos abierta la pestaña del navegador, pero tanto el cliente como el servidor pueden cerrar la conexión en cualquier momento.
Usos de los WebSockets
Los WebSocket son necesarios cuando debe de existir una comunicación constante entre el Servidor y el Cliente. Anteriormente a los WebSocket, el navegador tenía que consultar constantemente al servidor por nueva información, lo que lo hacía algo tedioso y representaba un problema de performance grave, ya que cuantos más usuarios teníamos conectados a nuestra página, más consultas se realizaban constantemente y en la mayoría de ellas no había datos nuevos que mostrar.
En la imagen podemos apreciar como el navegador realiza varias consultas al navegador para obtener las actualizaciones del servidor, sin embargo, en la mayoría de las consultas no se obtienen nuevas actualizaciones (en verde), si no que hasta pasadas varias actualizaciones se obtiene nuevos datos del servidor (amarillo). Por lo que podemos ver que todas las fechas verdes son consultas innecesarias que van a degradar el performance del servidor y probablemente también el de la base de datos. Lo peor de esto es que, a mayor número de usuarios conectados a la página mayor se acentúa el problema como podemos ver en la siguiente imagen.
En escenarios donde tenemos que obtener datos del servidor de forma constante siempre será mejor utilizar un WebSocket, para que de esta manera sea el mismo Servidor quien nos notifique de inmediato en cuando existan nuevos datos. De esta forma el servidor evita tener que procesar una serie de peticiones innecesarias. Veamos cómo quedaría el escenario anterior con WebSockets:
En esta nueva imagen ya podemos apreciar mucho mejor como es que los WebSocket mantiene la comunicación y de esta forma saber cuándo debemos utilizar los WebSockets. Lo primero que vemos en la imagen es que un navegador le envía información al Servidor, luego, el Servidor notifica los nuevos cambios a otros dos clientes, finalmente existe otros dos navegadores que están conectados, pero no son notificados por que la nueva información no es de su interés.
WebSocket y JavaScript
Aunque los WebSocket son una de las mejorar agregadas en HTML5, la realidad es que absolutamente todo lo referente a WebSocket del lado del cliente, se tiene que programar con JavaScript, y es desde aquí donde tendremos que establecer la conexión y gestionar el envío y recepción de mensajes. A continuación, te dejo un guía rápido de cómo utilizar WebSocket con JavaScript:
Estableciendo conexión con el servidor:
var socket = new WebSocket("SERVER_URL");
Esta línea nos permite establecer la conexión inicial con el servidor, como parámetro se debe de establecer la URL sobre la cual escucha el Servidor.
Enviando datos al servidor:
socket.send(“This is mi first message with WebSocket”);
La línea anterior se utiliza para enviar un mensaje al servidor, se puede enviar cualquier tipo de información, lo más normal es el envío de datos en formato Json.
Recibiendo datos del servidor:
socket.onmessage = function (event){ alert(event.data) }
Para recibir mensajes del servidor es necesario definir la función onmessage, la cual será ejecutada cuando se reciba nueva información del Servidor. En el ejemplo imprimo el contenido de event.data, el cual representa el mensaje recibido del Servidor.
Cerrando la conexión:
socket.closed();
Para cerrar la conexión con el Servidor solo es necesario ejecutar la función closed.
Eventos
socket.onerror = $function
Función ejecutada tras ocurrir un error.
socket.onclosed = $function
Función ejecutada cuando se cierra la conexión con el servidor.
socket.onopen = $function
Función ejecutada cuando se abre la conexión con el servidor.
Web Socket con Java
Te recomiendo que le des una revisada a este otro artículo en donde hablo de cómo implementar WebSocket con Java
Conclusiones
Como podemos apreciar, los WebSocket cambian totalmente el paradigma de la forma en que trabajábamos anteriormente con el servidor y un que pueda parecer un poco complejo, la realidad es que es mucho más fácil de utilizar de lo que parece, además que existe una serie de librerías para cada lenguaje que nos ayudan con el trabajo.
Excelente articulo, muchas gracias por sus aportes.
Gracias Carlos, que bueno que fue de utilidad 🙂
Excelente artículo. Muchas gracias
Gracias por el comentario José 🙂
Excelente artículo, muy bueno para introducirnos en el tema. Saludos desde El Salvador. CA.
Gracias por el comentario Josue, un saludo desde México
Hola, puedes responderme una pregunta? existe un limite de conexiones simultaneas utilizando un servidor ws en php con la clase php class.PHPWebSocket.php
https://github.com/Flynsarmy/PHPWebSocket-Chat/blob/master/class.PHPWebSocket.php
con un servidor vps de 1gb ram
gracias
Hola Javier, no he trabajado con PHP, sin embargo, no veo por que exista un límite máximo de conexiones, en tal caso, el límite lo podría la capacidad de tu servidor, es decir, mientras el servidor pueda mantener N conexiones abiertas no debería de haber problema, por otra parte, si el servidor se satura, siempre puedes manejar balanceo de cargar para poder habilitar otro servidor cuando el primario se sature.
saludos.
Gracias por tu tiempo, ¿tienes experiencia en websockets node? me podrías decir con los websocket en node cuantas conexiones a proximadamente puedo crear en un servidor de digital ocean de 1 gb ram y 1 cpu
Hola Javier, no sabría decirte exactamente cuantas conexiones puedes crear, nunca he hecho ese análisis, además, no solo depende de cuantas conexiones crees, si no que tanta data mandes por esas conexiones, sería cuestión de que hagas algunas pruebas, al final, recuerda que Digital Ocean te permite crecer tu servidor en caso de que llegues a un punto en el cual ya no sea suficiente un 1GB de RAM.
Hola Ocar, saludos desde Chile, exelente articulo de Websockets.
Consulta, como deberia hacerlo para enviar informacion via websocket de una pagina1 de Administrador que envia informacion de actualizacion a una pagina2 Clientes en linea en tiempo real.
La pagina2 Clientes con websocket funciona exelente, tipo chat pero necesito enviarles en todo momentos desde una pagina distinta Administrador datos en tiempo real que se actualicen en la pagina1 Clientes.
No se como se conectar la pagina2 con el websocket.
Se agradecera tu respuesta. Saludos de Chile.✌
Si lo que buscas es conectar una página con otra no podrás, ya que la conexión es entre página y servidor, en tal caso tendrías que pasar por el servidor, es decir, página1 -> servidor -> página2
Buenas Tardes. Me ha sido de gran ayuda tu tutorial. Una pregunta a ver si sabes responderme…
¿Se puede enviar a traves de los webSockets un archivo? en mi caso sería un pdf. Llevo pegandome bastante tiempo con este problema ya que no lo consigo hacer y todos los ejemplos que veo son con imagenes. Tengo en mi javaScript un base64 que es un pdf. Quiero enviarselo al cliente pero no hay manera. Si le paso un string normal si que me lo detecta pero el base 64 no… .
Mi codigo seria algo asi como websocket.send(); Dentro del send si le pongo el base64 me da error, si le pongo un string normal me deja. si le pongo un objeto y lo serializo con json tambien me deja.
Si me puedes ayudar te lo agradecería enormemente.
Un saludo y gracias.
hola, en realidad los websocket permite transmitir mensajes binarios, solo le tendrás que Serializar antes de mandarlo y deserializarlo al recibirlo, fuera de eso no veo por que tienes problemas, tendrías que analizar el tipo de error que te arroja.
saludos.
Almacena el archivo en una ruta temporal y envía la ruta de descarga del archivo al cliente.
No hay manera… ayer pobre deserializando y no funciono. Se que sera una tontería pero no la logro ver. ¿Te puedo pasar mi codigo de Javascript para ver si ves algo raro?. Me salto error, pero en el evt evt.data me sale undefined. No se… . Si puedes ponte en contacto conmigo en baradoinaki@gmail.com y hablamos mas directamente o te paso capturas del codigo o el propio proyecto y aver si ves algo raro….
Muchas gracias.
Hola Barado, lo siento, pero no no tengo mucho tiempo para revisar el código, solo te puedo ayudar con preguntas puntales.
Saludos
Hola,
Buen articulo, disculpa quisiera saber si podrias recomendar alguna libreria para implementar en MVC .net pero en javascript.
Saludos
Hola Ronny, te pregunta es confusa, como que una librería de .NET para ser implementada en JS?
Hola Oscar, me gusta mucho tus post, soy nuevo en esto de la programacion, pero si quiero compartir informacion de video y audio por UDP (entiendo que es mas rapido que TCP) tambien podria usar websockets ?
La verdad no he trabajado con video, pero no creo que sea una buena idea usar webhook para video, ya que los webhooks son mas que nada para mandar notificaciones del servidor al cliente, no tanto para transferencia pesada de archivos.
Excelente articulo oscar
Muchas gracias Wilfredo
<soy Programador C y Java pero sobre Socket(TCP/IP), entiendo todo el mecanismo de comunicacion y funcionamiento, lo que no me queda claro como del lado del servidor hay un .html y dentro de el se oculta un .class? o se necesita que todo el dominio + url lo maneje un ISP o un Webserver?