BLOG | NGINX

NGINX como proxy WebSocket

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Rick Nelson
Rick Nelson
Publicado el 16 de mayo de 2014

El protocolo WebSocket proporciona una forma de crear aplicações web que admiten la comunicación bidireccional en tiempo real entre clientes y servidores. Como parte de HTML5, WebSocket hace que sea mucho más fácil desarrollar este tipo de aplicações que los métodos disponibles anteriormente. La mayoría de los navegadores modernos admiten WebSocket, incluidos Chrome, Firefox, Internet Explorer, Opera y Safari, y cada vez más marcos de aplicação de servidor también admiten WebSocket.

Para el uso de producción empresarial, donde se necesitan múltiples servidores WebSocket para lograr rendimiento y alta disponibilidad, se requiere una capa de equilibrio de carga que comprenda el protocolo WebSocket, y NGINX ha admitido WebSocket desde la versión 1.3 y puede actuar como un proxy inverso y equilibrar la carga de las aplicações WebSocket. (Todas las versiones de NGINX Plus también admiten WebSocket).

Consulte las pruebas de rendimiento recientes sobre la escalabilidad de NGINX para equilibrar la carga de las conexiones WebSocket.

El protocolo WebSocket es diferente del protocolo HTTP, pero el protocolo de enlace WebSocket es compatible con HTTP y utiliza la función de actualización HTTP para actualizar la conexión de HTTP a WebSocket. Esto permite que las aplicações WebSocket se adapten más fácilmente a las infraestructuras existentes. Por ejemplo, las aplicações WebSocket pueden utilizar los puertos HTTP estándar 80 y 443, permitiendo así el uso de reglas de firewall existentes.

Una aplicação WebSocket mantiene abierta una conexión de larga duración entre el cliente y el servidor, lo que facilita el desarrollo de aplicações en tiempo real. El mecanismo de actualización HTTP utilizado para actualizar la conexión de HTTP a WebSocket utiliza los encabezados de actualización y conexión . Existen algunos desafíos que enfrenta un servidor proxy inverso al soportar WebSocket. Una de ellas es que WebSocket es un protocolo salto a salto, por lo que cuando un servidor proxy intercepta una solicitud de actualización de un cliente, necesita enviar su propia solicitud de actualización al servidor backend, incluidos los encabezados adecuados. Además, dado que las conexiones WebSocket son de larga duración, a diferencia de las típicas conexiones de corta duración que utiliza HTTP, el proxy inverso debe permitir que estas conexiones permanezcan abiertas, en lugar de cerrarlas porque parecen estar inactivas.

NGINX admite WebSocket al permitir que se configure un túnel entre un cliente y un servidor backend. Para que NGINX envíe la solicitud de actualización desde el cliente al servidor backend, los encabezados de actualización y conexión deben configurarse explícitamente, como en este ejemplo:

ubicación /wsapp/ { contraseña_proxy http://wsbackend;
versión_proxy_http 1.1;
encabezado_proxy Actualización $http_upgrade;
encabezado_proxy Conexión "Actualizar";
encabezado_proxy Host $host;
}

Una vez hecho esto, NGINX lo trata como una conexión WebSocket.

Ejemplo de WebSocket de NGINX

Aquí hay un ejemplo en vivo para mostrar cómo NGINX funciona como un proxy WebSocket. Este ejemplo utiliza ws , una implementación de WebSocket construida en Node.js. NGINX actúa como un proxy inverso para una aplicação WebSocket simple que utiliza ws y Node.js. Estas instrucciones se han probado con Ubuntu 13.10 y CentOS 6.5, pero es posible que sea necesario adaptarlas a otros sistemas operativos y versiones. Para este ejemplo, la dirección IP del servidor WebSocket es 192.168.100.10 y la dirección IP del servidor NGINX es 192.168.100.20.

  1. Si aún no tiene instalados Node.js y npm, ejecute el siguiente comando:

    • Para Debian y Ubuntu:

      $ sudo apt-get install nodejs npm
    • Para RHEL y CentOS:

      $ sudo yum install nodejs npm
  2. Node.js se instala como nodejs en Ubuntu y como node en CentOS. El ejemplo utiliza node , por lo que en Ubuntu necesitamos crear un enlace simbólico de nodejs a node :

    $ ln -s /usr/bin/nodejs /usr/local/bin/node
  3. Para instalar ws , ejecute el siguiente comando:

    $ sudo npm install ws

    Nota:  Si recibe el mensaje de error: “Error: no se pudo obtener del registro: ws”, ejecute el siguiente comando para solucionar el problema:

    $ sudo npm config set registry http://registry.npmjs.org/

    Luego ejecute nuevamente el comando sudo npm install ws .

  4. ws viene con el programa /root/node_modules/ws/bin/wscat que usaremos para nuestro cliente, pero necesitamos crear un programa que actúe como servidor. Crea un archivo llamado server.js con este contenido:

    console.log("Servidor iniciado");
    var Msg = '';
    var WebSocketServer = require('ws').Server
    , wss = new WebSocketServer({puerto: 8010});
    wss.on('conexión', function(ws) {
    ws.on('mensaje', function(mensaje) {
    console.log('Recibido del cliente: %s', mensaje);
    ws.send('Servidor recibido del cliente: ' + mensaje);
    });
    });
  5. Para ejecutar el programa del servidor, ejecute el siguiente comando:
    $ nodo server.js
  6. El servidor imprime un mensaje inicial "Servidor iniciado" y luego escucha en el puerto 8010, esperando que un cliente se conecte a él. Cuando recibe una solicitud de un cliente, la repite y envía un mensaje al cliente que contiene el mensaje que recibió. Para que NGINX procese estas solicitudes, creamos la siguiente configuración. Estamos agregando el bloque de mapa para que el encabezado de Conexión esté configurado correctamente para cerrarse cuando el encabezado de Actualización en la solicitud esté configurado en '' .

    http {
    map $http_upgrade $connection_upgrade {
    actualización predeterminada;
    '' cerrar;
    }
    
    websocket ascendente {
    servidor 192.168.100.10:8010;
    }
    
    servidor {
    escuchar 8020;
    ubicación / {
    contraseña de proxy http://websocket;
    versión de proxy http 1.1;
    encabezado_del_conjunto_del_proxy Actualización $http_upgrade;
    encabezado_del_conjunto_del_proxy Conexión $connection_upgrade;
    encabezado_del_conjunto_del_proxy Host $host;
    }
    }
    }

    NGINX escucha en el puerto 8020 y envía las solicitudes al servidor WebSocket de back-end. Las directivas proxy_set_header permiten que NGINX gestione correctamente el protocolo WebSocket.

  7. Para probar el servidor, ejecutamos wscat como nuestro cliente:

    $ /root/node_modules/ws/bin/wscat --connect ws://192.168.100.20:8020

    wscat se conecta al servidor WebSocket a través del proxy NGINX. Cuando escribe un mensaje para que wscat lo envíe al servidor, lo ve reflejado en el servidor y luego aparece un mensaje del servidor en el cliente. A continuación se muestra un ejemplo de interacción:

    Servidor: Cliente:
    $ nodo server.js
    Servidor iniciado
     
     
     
     
     
    wscat --connect ws://192.168.100.20:8020
    Conectado (presione CTRL+C para salir)
    > Hola
    Recibido del cliente: Hola
    < Servidor recibido del cliente: Hola

    Aquí vemos que el cliente y el servidor pueden comunicarse a través de NGINX, que actúa como proxy, y los mensajes pueden seguir enviándose de ida y vuelta hasta que el cliente o el servidor se desconecten. Todo lo que se necesita para que NGINX maneje WebSocket correctamente es configurar los encabezados correctamente para manejar la solicitud de actualización que actualiza la conexión de HTTP a WebSocket.

Más información


"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.