Creación de una aplicación web WebSocket y configuración de un proxy

11 de septiembre de 2023

Lang: cs en de es

El desarrollo de aplicaciones web modernas avanza constantemente hacia una mayor interactividad y una comunicación más rápida entre cliente y servidor. Tecnologías como WebSocket juegan un papel clave en esta dirección. En este curso aprenderás a crear una aplicación con WebSocket y a configurar correctamente los proxies para que WebSockets funcione. Con esto, usted será capaz de crear y ejecutar una aplicación altamente interactiva que proporcionará una buena experiencia de usuario.

Protocolo WebSocket

WebSocket es un protocolo que permite la comunicación bidireccional entre cliente y servidor, lo que lo convierte en una opción ideal para aplicaciones que requieren actualizaciones de datos rápidas y reactivas.
WebSocket es un protocolo de comunicación diseñado para la comunicación interactiva entre navegadores web y aplicaciones de servidor web. Su principal objetivo es proporcionar una conexión bidireccional persistente entre el cliente (navegador) y el servidor que permita una transferencia de datos inmediata y eficiente. WebSocket se utiliza a menudo en aplicaciones web modernas que requieren una comunicación rápida e interactiva entre clientes y servidor. En comparación con técnicas tradicionales como AJAX o el "sondeo largo", WebSocket proporciona un medio más eficaz y directo para la transferencia de datos en tiempo real.

Usos adecuados de WebSocket

Estos son algunos ejemplos de para qué es adecuado WebSocket:

  • Aplicaciones en tiempo real:
  • WebSocket es adecuado para desarrollar aplicaciones que requieren una comunicación instantánea y continua entre cliente y servidor. Esto es útil para aplicaciones de chat, juegos online, herramientas colaborativas y otras aplicaciones que necesitan una rápida sincronización de datos entre los diferentes usuarios de la aplicación.
  • Actualizaciones en tiempo real:
  • WebSocket permite al servidor enviar actualizaciones y alertas a los clientes sin tener que sondear al servidor repetidamente. Esto reduce la carga del servidor y acelera la respuesta a los eventos.
  • Transmisión de datos, Esto permite que grandes volúmenes de datos o un flujo continuo de audio/vídeo se transmitan secuencialmente sin requerir una carga completa o la caída de la conexión.
  • Comunicación eficiente:
  • WebSocket está diseñado para minimizar la sobrecarga de comunicación y permitir una transferencia de datos eficiente entre el cliente y el servidor. El protocolo está optimizado para reducir la latencia y garantizar un bajo retardo en la comunicación.
  • Servidor web

Uso inadecuado de WebSocket

WebSocket no es adecuado para todo tipo de comunicación y hay situaciones en las que otros protocolos o tecnologías pueden ser una mejor opción. Estos son algunos ejemplos en los que WebSocket puede no ser la mejor opción:
  • Sitios web tradicionales: Cuando se trata de sitios web estáticos regulares, que no necesitan comunicación bidireccional instantánea entre el cliente y el servidor, el uso de WebSocket es redundante. Para estos propósitos, el protocolo HTTP regular o su versión cifrada de HTTPS, que asegura la comunicación con un certificado.
  • Comunicación unidireccional: cuando la aplicación sólo requiere comunicación unidireccional del servidor al cliente (por ejemplo, envío de actualizaciones o información desde el servidor), Existen alternativas más sencillas, como los Eventos Enviados por el Servidor (SSE) o técnicas de sondeo largas que pueden encajar mejor.
  • Alta carga del servidor: si tiene una aplicación con un gran número de usuarios concurrentes o espera un alto tráfico, especialmente con un gran volumen de tráfico de datos, utilizar WebSocket puede aumentar la carga del servidor. En estos casos, debe considerar cuidadosamente las capacidades de escalabilidad y rendimiento del servidor.
  • Entornos con soporte limitado:Aunque los navegadores modernos soportan WebSocket, hay situaciones en las que se necesitan navegadores o entornos más antiguos que pueden no ser totalmente compatibles con WebSocket. En estos casos, sería necesario elegir alternativas compatibles con versiones anteriores.
  • Es importante tener en cuenta los requisitos y necesidades de una aplicación en particular antes de decidir utilizar WebSocket u otra tecnología. A veces, un protocolo o enfoque diferente puede ser una mejor opción para lograr una comunicación óptima entre el cliente y el servidor.

Vídeo de demostración de WebSocket

Puedes ver cómo usar WebSocket virtualmente en este vídeo con una aplicación demo que se comunica entre sí usando WebSocket y puedes ver el cursor de otros usuarios.

Programación de aplicaciones WebSocket

A la hora de crear una aplicación con WebSocket, es fundamental tener en cuenta que dicha aplicación consta de dos partes principales:
  1. Backend: Esta parte de la aplicación se ejecuta en el lado del servidor y puede implementarse en diversos lenguajes de programación como Python, JavaScript y otros. En este caso, te mostraremos cómo crear esta parte en JavaScript y ejecutarla utilizando Node.js.
  2. Frontend: El frontend suele estar escrito en JavaScript y se ejecuta directamente en el navegador web.

Servidor

El código fuente de la aplicación WebSocket Server que envía el mensaje recibido de vuelta al cliente. La librería WebSocket (WS) debe estar instalada para su funcionamiento.

/// npm install ws
const WebSocket = require('ws');

// Crear un servidor WebSocket en el puerto 8080
const wss = new WebSocket.Server({puerto: 8080});

// Evento que se dispara cuando el cliente se conecta
wss.on('connection', (ws) => {
    console.log('Nueva conexión establecida.');

    // Evento que se dispara cuando se recibe un mensaje del cliente
    ws.on('mensaje', (mensaje) => {
        console.log('Mensaje de cliente recibido: ' + mensaje);

        // Envío del mensaje al cliente
        ws.send(mensaje);
    });

    // Evento que se dispara cuando finaliza la conexión con el cliente
    ws.on('close', () => {
        console.log('La conexión con el cliente se ha cerrado.');
    });
});

console.log('El servidor WebSocket se está ejecutando en el puerto 8080.');

Puedes simplemente ejecutar este programa usando Node.js para obtener un servidor WebSocket completamente funcional.

Cliente

La página contiene un programa HTML y JavaScript que se conecta automáticamente al servidor WebSocket y permite enviar mensajes, a la vez que muestra los mensajes recibidos en tiempo real.

<html>
<head>
</head>
<body>
<form id="input-form "v
<label for="mensaje">Introduzca el mensaje:</label>
  	<input type="text" id="mensaje" name="mensaje"><br><br>
  	<input type="submit" value="Enviar">
</form>
<div id="mensajes"></div>
<script>

    // conexión directa a webSocket en nodeJS, no encriptada
    webSocket = new WebSocket('ws://localhost:8080');


    // ---- connet to webSocket in node JS via apache proxy
    // no encriptado
   // webSocket = new WebSocket('ws://localhost:81/'); //ok to apache and http
    //encriptado, necesito aceptar certificado propio
    //(abrir URL https://localhost:4441 y aceptar certificado)
    //webSocket = new WebSocket('wss://localhost:4441/');

    // ---- connet to webSocket in nodeJS via nginx proxy
    // no encriptado
    //webSocket = new WebSocket('ws://localhost:82/'); //ok en apache y http
    //encriptado, necesito aceptar certificado propio
    //(abrir URL https://localhost:4442 y aceptar certificado)
    //webSocket = new WebSocket('wss://localhost:4442/');

    webSocket.onmessage = (evento) => {
        console.log(evento)
        document.getElementById('mensajes').innerHTML +=
            'Mensaje del servidor: ' + event.data + "<br>";
    };
    webSocket.addEventListener("open", () => {
        console.log("Estamos conectados");
    });

    function sendMessage(event) {
        var inputMessage = document.getElementById('mensaje')
        webSocket.send(inputMessage.value)
        inputMessage.value = ""
        event.preventDefault();
    }

    document.getElementById('input-form').addEventListener('submit', sendMessage);
</script>
</body>
</html>

En este ejemplo, el cliente establece una conexión con un WebSocket que se ejecuta en el puerto 8080 sin cifrado.

Demo de la aplicación

El código fuente completo está en: https://github.com/josefjebavy/docker/tree/master/proxy-websocket. Hay configuraciones para docker y lanzamiento. Así que usando docker-compose up puedes preparar y ejecutar todo el proyecto de ejemplo y probar la funcionalidad WebSocket.

Proxy

Hoy en día es común que las aplicaciones web se ejecuten detrás de un proxy. Describí cómo configurar dicho proxy en el artículo webapplications behind a proxy. Sin embargo, si se utiliza WebSocket, todavía es necesario configurar el proxy.

Para este tutorial, asumo el caso que tienes. servidor Linux instalado con un servidor web Apache o Nginx que servirá como proxy.

Proxy Nginx

Para ejecutar Nginx como proxy y con un WebSocket funcionando, necesitas configurar el proxy de la siguiente manera:
location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $puerto_servidor;
    proxy_set_header X-Forwarded-Host $host;
                
    proxy_http_version 1.1;
    proxy_set_header Actualización $http_actualización;
    proxy_set_header Connection "actualización";
    proxy_pass http://nodejs:8080;
}

Proxy Apache

Apache necesita habilitar el soporte para proxy y WebSocket activando los módulos apropiados para el servidor web Apache. Y también será necesario el soporte de rewrite. En las distribuciones base Debian se puede hacer por ejemplo con el siguiente comando:

 a2enmod rewrite proxy proxy_http proxy_wstunnel
A continuación puedes añadir la siguiente configuración a la configuración de la aplicación web correspondiente (configuración del virtualhost), por ejemplo:
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://nodejs:8080/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
 RewriteRule /(.*) http://nodejs:8080/$1 [P,L]

Este es el aspecto que puede tener la infraestructura al ejecutar una aplicación proxy. A efectos de pruebas y entrenamiento he creado una aplicación demo donde como se puede ver en la imagen se puede comunicar:

  1. Directamente - sin proxy
  2. A través de un proxy proporcionado por el servidor web Apache
  3. Otro servidor donde el servidor web Nginx está configurado como proxy
proxy y websocket

De nuevo, toda la configuración se puede encontrar en GitHub en el proyecto: https://github.com/josefjebavy/docker/tree/master/proxy-websocket.

WebSocket cifrado

Cuál es la diferencia entre WS y WSS que se especifica al conectarse al servidor en la URL ws://localhost:808. La diferencia es la seguridad. WS indica tráfico no cifrado. WSS indica comunicación cifrada mediante SSL o actualmente TSL. Para más información, consulte HTTPS web security.

Si una aplicación web se comunica a través de un websocket cifrado (wss), el navegador debe considerar válido el certificado. Para un servidor con un certificado no válido, rechazará conectarse al WebSocket. Para hacer pruebas, normalmente utilizas algún certificado generado por ti y por lo tanto el certificado no es válido, entonces la solución más fácil es abrir la URL del servidor web y validar manualmente el certificado.

Video tutorial sobre WebSocket y Proxy

En este vídeo verás una completa demostración y descripción de cómo conseguir que una aplicación WebSocket funcione como cliente y servidor, y cómo configurar correctamente Apache y Nginx como proxy incluyendo un WebSocket que funcione.

Enlaces

Ejemplo de WebSocket
Wikipedia: WebSocket -Proxy_traversal
desarrollador mozilla: Escribir_aplicaciones_cliente_WebSocket
nginx: websocket

Funcionamiento de la aplicación web

Asegúrese de configurar de forma segura su servidor y de diseñar y programar su aplicación para que sea estable y segura. Porque la inestabilidad comprometerá la disponibilidad del servicio. Y si no presta atención a la seguridad, existe el riesgo de que alguien robe o borre sus datos, poniendo en riesgo su negocio. Sin embargo, no existe una guía sencilla para la seguridad, por lo que es necesario contratar a un IT consultor.

Las aplicaciones que utilizan WebSocket exigen más el rendimiento necesario del servidor y también son más complejas. Por eso deberías antes de presentar deberían haber llevado a cabo con mucho más detalle en el tráfico público pruebas de carga. Y determine el tráfico de usuarios esperado dimensionar los servidores en consecuencia y optimizar la arquitectura de aplicaciones e infraestructura. De lo contrario, no se puede esperar que después La publicación de la aplicación puede resistir el ataque de acceso de los usuarios.

Artículos sobre un tema similar

Análisis de la asignación y fijación de precios del desarrollo de proyectos de software
Programa Python para controlar Docker mediante la API
Cómo utilizar MailCatcher para probar correos electrónicos
API OpenAI de Python
Gestión de proyectos: desarrollo ágil de software
Cómo ejecutar aplicaciones PHP antiguas
Lo que debe saber un buen programador
Lenguaje de programación Rust
NodeJS: desarrollo, configuración del servidor
Fallo de seguridad de Nette CVE-2020-15227
API REST: API de plataforma
Alojamiento web y de correo personalizado con el software ISP Config
Programación en SQL: PostgreSQL, MySQL/MariaDB
HTTPS: web segura
Base de datos NoSQL Mongo DB
Connecting to Microsoft SQL Server from Linux
¿Cuál es la descripción del trabajo de un programador?
Localización de aplicaciones Python
Qué correo y alojamiento web elegir
Digispark - Programar microcontrolador Atmel ATtiny con Arduino IDE
Desarrollo para procesadores ARM con Arduino IDE
Cómo programar el procesador WiFi ESP8266
Smartphone abierto con Linux - Openmoko Neo FreeRunner

Boletin informativo

Si está interesado en recibir noticias puntuales por correo electrónico.
Puedes registrarte rellenando tu email suscripción de noticias.


+