Nginx 1.1 e Websockets (Socket.io, Faye, etc)

O Nginx é um servidor e proxy reverso open source de HTTP/HTTPS, SMTP, POP3 e IMAP, com foco em performance, concorrência e baixo uso de memória. O Nginx é absolutamente fenomenal para entregar conteúdo em alta velocidade, mas recentemente me deparei com um problema.

Datacenter

Não é possível utilizar Websockets atrás de um proxy reverso do Nginx. O motivo é que Websockets utilizam conexões HTTP/1.1, mas o módulo de proxy reverso do Nginx aceita somente conexões HTTP/1.0. Do lado do cliente o servidor é totalmente compatível, porém, do lado do upstream a realidade é outra.

Existem algumas soluções que podem ser aplicadas, como o uso do tcp_proxy ou até mesmo um outro servidor de proxy reverso. O tcp_proxy não permite que você utilize uma porta já utilizada por um módulo HTTP e outros proxies reversos em geral quebram o suporte a multiplos certificados SSL em um mesmo IP.

Este problema porém já foi corrigido na versão de desenvolvimento do Nginx, atualmente 1.1.16 (no momento em que este post foi escrito), mas não existem exemplos claros de como utilizar um Websocket atrás de um proxy reverso do Nginx nesta versão, motivo que me levou a escrever este post. Entendo que este conteúdo talvez fosse mais útil se escrito em inglês, mas não queria misturar um artigo em outro idioma no meio do blog e muito menos criar um somente para este fim.

Basicamente, as diretivas do módulo ngx_http_proxy_module que fazem a mágica são:

proxy_http_version 1.1;
proxy_buffering off;
proxy_cache_bypass $http_pragma $http_authorization;
proxy_no_cache $http_pragma $http_authorization;

Estes vão logo abaixo da diretiva proxy_pass no seu arquivo de configuração. Explicando melhor:

  • proxy_http_version: faz com que seja utilizado HTTP/1.1 para comunicação com o upstream;
  • proxy_buffering: por padrão, o nginx armazena o retorno do upstream em um buffer conforme vai recebendo e envia tudo para o cliente (browser) no final. Desabilitando o buffering, o Nginx passa a enviar imediatamente a resposta ao cliente a medida que vai recebendo do upstream;
  • proxy_cache_bypass e proxy_no_cache: faz com que o Nginx não armazene em cache conteúdo recebido do upstream caso contenham o header no-cache ou seja uma autenticação HTTP.

Se ficou alguma dúvida, poste nos comentários.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>