Neste post, falaremos sobre o uso do NGINX e do NGINX Plus com Node.js e Socket.IO. Nosso post sobre a criação de aplicações web em tempo real com WebSocket e NGINX tem sido bastante popular. Por isso, neste post, daremos continuidade ao assunto com documentação e práticas recomendadas para o uso do Socket.IO.
Por que usar o NGINX com Node.js e Socket.IO?
O Socket.IO é uma API de WebSocket que se tornou bastante popular com o crescimento das aplicações Node.js. A API é bastante conhecida por facilitar a criação de aplicações em tempo real, como jogos online ou chats. O NGINX 1.3.13 e versões posteriores, assim como todas as versões do NGINX Plus, oferecem suporte ao proxy de conexões WebSocket, permitindo o uso do Socket.IO. O protocolo WebSocket permite a comunicação full-duplex, ou bidirecional, por meio de uma única conexão TCP.
Aplicações em execução em ambientes de produção geralmente precisam operar na porta 80 (HTTP), na porta 443 (HTTPS) ou em ambas. Isso pode ser um desafio se vários componentes da sua aplicação interagirem com o usuário ou se você estiver usando um servidor web na porta 80 para fornecer outros recursos. Por isso, é necessário usar um proxy para o servidor Socket.IO, e o NGINX é a melhor maneira de fazer isso. Independentemente de você ter uma única instância da sua aplicação de backend ou centenas delas, o NGINX também pode balancear a carga dos seus servidores upstream ao usar vários nós.
Configuração do Socket.IO
Para instalar o Node.js, baixe a distribuição apropriada (ou instale-o usando um gerenciador de pacotes). Execute o comando npm install socket.io para instalar o Socket.IO.
Neste exemplo, pressupomos que o servidor Socket.IO do seu aplicativo em tempo real esteja sendo executado na porta 5000. Veja a seguir um modelo de arquivo de aplicativo Node server.js; trata-se de um programa básico que atua como servidor e encaminha as solicitações recebidas para a porta correta na qual o servidor Socket.IO está sendo executado.
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);
});
});
});Adicione um código JavaScript como o seguinte ao arquivo que é enviado ao seu cliente, por exemplo, index.html. Este exemplo solicita uma conexão com seu aplicativo para criar um WebSocket com o navegador do usuário.
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io(); // your initialization code here.
</script>Configuração do NGINX
Declaração de upstream
O NGINX e o NGINX Plus podem balancear a carga e distribuir as sessões dos usuários entre vários nós caso seu aplicativo tenha várias instâncias. No contexto http da configuração do NGINX ou NGINX Plus, inclua um bloco upstream para definir os nós de um grupo upstream.
Como mostrado no exemplo a seguir, você pode incluir o parâmetro weight em uma diretiva server para definir a proporção do tráfego direcionado a ela. Nesse caso, srv1.app.com recebe cinco vezes mais sessões do que os outros servidores. O NGINX Plus amplia os recursos de proxy reverso do NGINX com métodos avançados de balanceamento de carga e adiciona persistência de sessão, verificações de integridade, relatórios de status detalhados e reconfiguração dinâmica de grupos de servidores com balanceamento 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;
}Configuração do host virtual
Agora que o grupo de servidores upstream foi declarado, é necessário configurar um servidor virtual para direcionar o tráfego a ele. Inclua, no mínimo, a diretiva proxy_pass e especifique o nome do grupo upstream. Como o protocolo WebSocket usa o cabeçalho Upgrade, introduzido no HTTP/1.1, incluímos a diretiva 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;
}
}E quanto aos arquivos estáticos?
Para disponibilizar arquivos estáticos, você pode configurar o NGINX para encaminhar as solicitações a uma instância upstream do Node.js, mas, na maioria dos casos, é mais eficiente fazer com que o próprio NGINX os sirva diretamente.
Em conjunto com a diretiva server_name no bloco server acima, o bloco location a seguir instrui o NGINX a responder às solicitações dos clientes por conteúdo em http://app.domain.com/assets/ servindo-o a partir do diretório local /path/to/assets. Você também pode otimizar o processamento de arquivos estáticos ou definir configurações de expiração de cache que atendam às suas necessidades.
location /assets {
alias /path/to/assets;
access_log off;
expires max;
}Solução de problemas
Se você receber o erro a seguir, provavelmente está executando uma versão do NGINX anterior à 1.3. O uso de WebSocket é compatível com o NGINX 1.3.13 e versões posteriores.
WebSocket connection to '...' failed: Error during WebSocket handshake: 'Connection' header value is not 'Upgrade': keep-alive socket.io.js:2371Leitura complementar
- NGINX como proxy WebSocket
- Comparação de recursos do NGINX e do NGINX Plus
- Especificações técnicas do NGINX Plus
Para experimentar o NGINX Plus, comece hoje mesmo sua avaliação gratuita de 30 dias ou entre em contato conosco para conversar sobre seus casos de uso.
Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.