Configurando o Apache 2.4 mod_proxy_wstunnel para Socket.IO 1.0

15

Estou tentando configurar o Apache 2.4 para proxy da conexão websocket do socket.io para um servidor node.js websocket, usando mod_proxy_wstunnel. Tivemos isso funcionando bem com o socket.io 0.9, mas com a versão 1.0 eles mudaram o terminal do soquete para um parâmetro de consulta e agora estou tendo problemas para configurar o apache com as instruções corretas do proxy.

Todas as solicitações para /socket.io/?EIO=N&transport=websocket(onde N é qualquer dígito, geralmente 2) precisam ser encaminhadas ws://localhost:8082/socket.io/, mas todas as outras solicitações precisam ser encaminhadas http://localhost:8082/socket.io/.

Eu tentei variações das duas configurações a seguir:

ProxyPass /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket
ProxyPassReverse /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

.

RewriteRule /socket.io/?EIO=([0-9]+)&transport=websocket ws://localhost:8082/socket.io/ [QSA,P]

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

Concluí no meu blog que o ProxyPass e Locations não podem segmentar cadeias de caracteres de consulta, então existe alguma outra opção aqui? Os caminhos são codificados no socket.io, de modo que não é possível alterá-los por toda a biblioteca.

ChiperSoft
fonte

Respostas:

39

Use as condições de reescrita para corresponder a este caso especial:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:8082/$1 [P,L]

ProxyPass        /socket.io http://localhost:8082/socket.io
ProxyPassReverse /socket.io http://localhost:8082/socket.io

NOTA Como Mark W anotou abaixo. Eles devem ser inseridos no nível do vhost e não no servidor ou no nível do .htaccess.

Você também pode fazer referência a um balanceador:

<Proxy balancer://http-localhost/>
    BalancerMember http://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember http://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    ProxySet lbmethod=bytraffic
</Proxy>

<Proxy balancer://ws-localhost/>
    BalancerMember ws://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember ws://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    ProxySet lbmethod=bytraffic
</Proxy>

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io                [NC]
RewriteCond %{QUERY_STRING} transport=websocket        [NC]
RewriteRule /(.*)           balancer://ws-localhost/$1 [P,L]

ProxyPass        /socket.io balancer://http-localhost/socket.io
ProxyPassReverse /socket.io balancer://http-localhost/socket.io
PeterPramb
fonte
+100000 Você fez o meu dia. Estive nisso por horas. Eu usei o primeiro trecho de código. Eu não preciso de um balanceador no momento.
Eamorr
Não consigo fazer isso funcionar. O Apache continua respondendo com um código 404. Ele aparece no log de acesso como se estivesse tentando carregar um arquivo normal, e o processo do nó do soquete não mostra sinais de recebimento da solicitação (mostra a chamada para o arquivo socket.io.js.)
ChiperSoft
1
Parece que mod_rewrite não conhece o protocolo ws: //. Eu vejo isso no meu log de reescrita: forcing proxy-throughput with http://[REDACTED].dev/ws://localhost:8082/socket.io/(
domain.dev
Isto é provavelmente porque: issues.apache.org/bugzilla/show_bug.cgi?id=55598 olhares como suporte para o protocolo foi adicionado em Apache 2,5
ChiperSoft
5
NOTA : Esses blocos devem ser colocados dentro do <VirtualHost>bloco na ordem exata descrita, mesmo se você estiver usando a raiz do documento (por exemplo /var/www/html). Passei quase duas horas tentando descobrir por que essas mudanças não estavam funcionando corretamente, apenas para descobrir que RewriteRuleelas não estavam funcionando no nível raiz httpd.conf(embora ProxyPassestivesse funcionando). As ProxyPassdiretivas não funcionam em <Directory>blocos ou .htaccessarquivos (embora funcionem RewriteRule); portanto, é o local lógico para agrupar essas alterações <VirtualHost>.
Mark W