BLOG | NGINX

Usando NGINX y NGINX Plus con Node.js y Socket.IO, la API WebSocket

Miniatura de Patrick Nommensen
Patrick Nommensen
Publicado el 19 de noviembre de 2014

En esta publicación hablaremos sobre el uso de NGINX y NGINX Plus con Node.js y Socket.IO. Nuestra publicación sobre la creación de aplicaciones web en tiempo real con WebSocket y NGINX ha sido bastante popular, por lo que en esta publicación continuaremos con la documentación y las mejores prácticas utilizando Socket.IO.

¿Por qué utilizar NGINX con Node.js y Socket.IO?

Socket.IO es una API de WebSocket que se ha vuelto bastante popular con el auge de las aplicaciones Node.js. La API es bien conocida porque facilita la creación de aplicaciones en tiempo real, como juegos en línea o chat. NGINX 1.3.13 y posteriores y todas las versiones de NGINX Plus admiten el proxy de conexiones WebSocket, lo que le permite utilizar Socket.IO. El protocolo WebSocket permite la comunicación full-duplex o bidireccional a través de una única conexión TCP.

Las aplicações que se ejecutan en producción generalmente necesitan ejecutarse en el puerto 80 (HTTP), el puerto 443 (HTTPS) o ambos. Esto puede ser un desafío si varios componentes de su aplicación interactúan con el usuario o si está utilizando un servidor web en el puerto 80 para entregar otros activos. Esto hace que sea necesario utilizar un proxy hacia el servidor Socket.IO, y NGINX es la mejor manera de hacerlo. Ya sea que tenga una instancia de su aplicación backend o cientos, NGINX también puede equilibrar la carga de sus aplicaciones ascendentes cuando utiliza múltiples nodos.

Configuración de Socket.IO

Para instalar Node.js, descargue la distribución adecuada (o instálela con un administrador de paquetes ). Ejecute el comando npm install socket.io para instalar Socket.IO.

Para este ejemplo, suponemos que el servidor Socket.IO de su aplicación en tiempo real se ejecuta en el puerto 5000. La siguiente es una plantilla para un archivo de aplicación de nodo server.js ; es un programa básico que actúa como un servidor y enruta las solicitudes entrantes al puerto adecuado que ejecuta el servidor Socket.IO.

var io = require('socket.io').listen(5000); 
io.sockets.on('connection', function (socket) {
  socket.on('set nickname', function (name) {
    socket.set('nickname', name, function () {
      socket.emit('ready');
    });
  });
 
  socket.on('msg', function () {
    socket.get('nickname', function (err, name) {
      console.log('Chat message by ', name);
    });
  });
});

Agregue código JavaScript como el siguiente al archivo que se entrega a su cliente, por ejemplo index.html . Este ejemplo solicita una conexión a su aplicación para crear un WebSocket con el navegador de su usuario.

<script src="/socket.io/socket.io.js"></script>
<script>
     var socket = io(); // your initialization code here.
</script>

Configuración de NGINX

Declaración Upstream

NGINX y NGINX Plus pueden equilibrar la carga y distribuir sesiones de usuario a múltiples nodos si su aplicación tiene varias instancias. En el contexto http de su configuración NGINX o NGINX Plus, incluya un bloque ascendente para definir los nodos en un grupo ascendente.

Como se muestra en el siguiente ejemplo, puede incluir el parámetro de peso en una directiva de servidor para establecer la proporción de tráfico dirigido a él. Aquí srv1.app.com recibe cinco veces más sesiones que los otros servidores. NGINX Plus amplía las capacidades de proxy inverso de NGINX con métodos de equilibrio de carga mejorados y agregando persistencia de sesión, controles de estado, informes de estado extendidos y reconfiguración sobre la marcha de grupos de servidores con equilibrio de carga.

# in the http{} configuration block
upstream socket_nodes {
    ip_hash;
    server srv1.app.com:5000 weight=5;
    server srv2.app.com:5000;
    server srv3.app.com:5000;
    server srv4.app.com:5000;
}

Configuración de host virtual

Ahora que se ha declarado el grupo de servidores ascendente, es necesario configurar un servidor virtual para dirigir el tráfico hacia él. Como mínimo, incluya la directiva proxy_pass y nombre el grupo ascendente. Debido a que el protocolo WebSocket utiliza el encabezado Upgrade introducido en HTTP/1.1, incluimos la directiva proxy_http_version .

server {
    server_name app.domain.com;
    location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://socket_nodes;
    }
}

¿Qué pasa con los archivos estáticos?

Para entregar activos estáticos, puede hacer que NGINX envíe solicitudes de proxy a una instancia Node.js ascendente, pero en la mayoría de los casos es más eficiente que NGINX las atienda directamente.

En combinación con la directiva server_name en el bloque de servidor anterior, el siguiente bloque de ubicación le indica a NGINX que responda a las solicitudes de los clientes de contenido en http://app.domain.com/assets/ sirviéndolo desde el directorio local /path/to/assets . Puede optimizar aún más el manejo de archivos estáticos o establecer configuraciones de expiración de caché que satisfagan sus necesidades.

location /assets {
    alias /path/to/assets;
    access_log off;
    expires max;
}

Solución de problemas

Si recibe el siguiente error, probablemente esté ejecutando una versión de NGINX anterior a la 1.3. El uso de WebSocket es compatible con NGINX 1.3.13 y versiones posteriores.

WebSocket connection to '...' failed: Error during WebSocket handshake: 'Connection' header value is not 'Upgrade': keep-alive socket.io.js:2371

Más información

Para probar NGINX Plus, comience hoy su prueba gratuita de 30 días o contáctenos para analizar sus casos de uso.


"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.