O protocolo WebSocket oferece uma maneira de criar aplicações web compatíveis com a comunicação bidirecional em tempo real entre clientes e servidores. Como parte do HTML5, o WebSocket facilita muito o desenvolvimento desses tipos de aplicação em comparação com os métodos disponíveis anteriormente. A maioria dos navegadores modernos é compatível com o WebSocket, incluindo Chrome, Firefox, Internet Explorer, Opera e Safari, e cada vez mais frameworks de aplicações para servidores também oferecem suporte ao WebSocket.
Para uso em produção empresarial, em que vários servidores WebSocket são necessários para garantir desempenho e alta disponibilidade, é preciso contar com uma camada de balanceamento de carga que compreenda o protocolo WebSocket. O NGINX oferece suporte a WebSocket desde a versão 1.3 e pode atuar como um proxy reverso e realizar o balanceamento de carga de aplicações WebSocket. (Todas as versões do NGINX Plus também oferecem suporte a WebSocket.)
Confira os recentes testes de desempenho sobre a escalabilidade do NGINX para balancear a carga de conexões WebSocket.
O protocolo WebSocket é diferente do protocolo HTTP, mas o handshake do WebSocket é compatível com HTTP e usa o mecanismo HTTP Upgrade para atualizar a conexão de HTTP para WebSocket. Isso permite que as aplicações WebSocket se integrem mais facilmente às infraestruturas existentes. Por exemplo, as aplicações WebSocket podem usar as portas HTTP padrão 80 e 443, possibilitando assim o uso das regras de firewall existentes.
Uma aplicação WebSocket mantém uma conexão de longa duração aberta entre o cliente e o servidor, facilitando o desenvolvimento de aplicações em tempo real. O mecanismo HTTP Upgrade usado para atualizar a conexão de HTTP para WebSocket utiliza os cabeçalhos Upgrade e Connection. Há alguns desafios que um servidor proxy reverso enfrenta ao oferecer suporte a WebSocket. Um deles é que o WebSocket é um protocolo salto a salto; portanto, quando um servidor proxy intercepta uma solicitação de Upgrade de um cliente, ele precisa enviar sua própria solicitação de Upgrade ao servidor de backend, incluindo os cabeçalhos apropriados. Além disso, como as conexões WebSocket são de longa duração, ao contrário das conexões normalmente curtas usadas pelo HTTP, o proxy reverso precisa permitir que essas conexões permaneçam abertas, em vez de fechá-las por parecerem ociosas.
O NGINX oferece suporte a WebSocket permitindo a criação de um túnel entre um cliente e um servidor de backend. Para que o NGINX envie a solicitação de Upgrade do cliente ao servidor de backend, os cabeçalhos Upgrade e Connection devem ser definidos explicitamente, como neste exemplo:
location /wsapp/ { proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}Feito isso, o NGINX passa a tratar essa conexão como uma conexão WebSocket.
Exemplo de WebSocket com NGINX
Veja um exemplo prático que mostra o NGINX funcionando como um proxy WebSocket. Este exemplo usa o ws, uma implementação de WebSocket desenvolvida com Node.js. O NGINX atua como proxy reverso para uma aplicação WebSocket simples que utiliza o ws e o Node.js. Estas instruções foram testadas no Ubuntu 13.10 e no CentOS 6.5, mas talvez precisem ser adaptadas para outros sistemas operacionais e versões. Neste exemplo, o endereço IP do servidor WebSocket é 192.168.100.10, e o endereço IP do servidor NGINX é 192.168.100.20.
- Se você ainda não tiver o Node.js e o npm instalados, execute o seguinte comando:
- Para Debian e Ubuntu:
$ sudo apt-get install nodejs npm- Para RHEL e CentOS:
$ sudo yum install nodejs npm- O Node.js é instalado como
nodejsno Ubuntu e comonodeno CentOS. O exemplo usanode, portanto, no Ubuntu, precisamos criar um link simbólico denodejsparanode:
$ ln -s /usr/bin/nodejs /usr/local/bin/node- Para instalar o ws, execute o seguinte comando:
$ sudo npm install ws- Observação: Se você receber a mensagem de erro: “Erro: falha ao buscar no registro: ws”, execute o seguinte comando para corrigir o problema:
$ sudo npm config set registry http://registry.npmjs.org/- Em seguida, execute o comando
sudo npm install wsnovamente. - ws vem com o programa /root/node_modules/ws/bin/wscat que usaremos para o nosso cliente, mas precisamos criar um programa para atuar como servidor. Crie um arquivo chamado server.js com o seguinte conteúdo:
console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8010});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('Received from client: %s', message);
ws.send('Server received from client: ' + message);
});
});- Para executar o programa do servidor, execute o seguinte comando:
$ node server.js- O servidor exibe uma mensagem inicial
"Servidoriniciado"e, em seguida, começa a escutar na porta 8010, aguardando a conexão de um cliente. Ao receber uma solicitação de um cliente, ele a repete e envia de volta ao cliente uma mensagem contendo a mensagem recebida. Para que o NGINX encaminhe essas solicitações por proxy, criamos a configuração a seguir. Adicionamos o blocomappara que o cabeçalhoConnectionseja definido corretamente comoclosequando o cabeçalhoUpgradeda solicitação estiver definido como''.
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 192.168.100.10:8010;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
}- O NGINX escuta na porta 8020 e encaminha as solicitações ao servidor WebSocket de backend. As diretivas
proxy_set_headerpermitem que o NGINX processe corretamente o protocolo WebSocket. - Para testar o servidor, executamos o wscat como nosso cliente:
$ /root/node_modules/ws/bin/wscat --connect ws://192.168.100.20:8020- wscat se conecta ao servidor WebSocket por meio do proxy NGINX. Quando você digita uma mensagem para o wscat enviar ao servidor, ela é exibida no servidor e, em seguida, uma mensagem do servidor aparece no cliente. Veja um exemplo de interação: Servidor: Cliente:
$node server.jsServidor iniciado
wscat --connect ws://192.168.100.20:8020
Conectado (pressione CTRL+C para sair)
> OláRecebido do cliente: Olá< O servidor recebeu do cliente: OláAqui vemos que o cliente e o servidor conseguem se comunicar por meio do NGINX, que atua como proxy, e que as mensagens podem continuar sendo enviadas em ambas as direções até que o cliente ou o servidor se desconecte. Para que o NGINX processe corretamente o WebSocket, basta configurar os cabeçalhos de forma adequada para processar a solicitação de Upgrade, que atualiza a conexão de HTTP para WebSocket.
Leitura adicional
- Proxy reverso de WebSocket no nginx.org
- Comparação de recursos do NGINX e do NGINX Plus
- Especificações técnicas do NGINX Plus
- Configuração de proxy para tráfego WebSocket em:
- Balanceamento de carga de servidores Apache Tomcat com NGINX Open Source e NGINX Plus
- Balanceamento de carga de servidores de aplicações Node.js com NGINX Open Source e NGINX Plus
- Balanceamento de carga do Oracle WebLogic Server com NGINX Open Source e NGINX Plus
- Balanceamento de carga dos servidores de aplicações WildFly e JBoss com NGINX Open Source e NGINX Plus
Sobre o autor

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.