Configuración de Apache 2.4 mod_proxy_wstunnel para Socket.IO 1.0

15

Estoy tratando de configurar Apache 2.4 para enviar la conexión websocket para socket.io a un servidor websocket node.js, usando mod_proxy_wstunnel. Esto funcionaba bien con socket.io 0.9, pero con la versión 1.0 cambiaron el punto final del socket a un parámetro de consulta, y ahora tengo problemas para configurar Apache con las instrucciones de proxy correctas.

Todas las solicitudes a /socket.io/?EIO=N&transport=websocket(donde N es cualquier dígito, generalmente 2) deben reenviarse ws://localhost:8082/socket.io/, pero todas las demás solicitudes deben reenviarse a http://localhost:8082/socket.io/.

He intentado variaciones de las dos configuraciones siguientes:

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/

De mi búsqueda en Google he deducido que ProxyPass y Locations no pueden orientar cadenas de consulta, entonces, ¿hay alguna otra opción aquí? Las rutas están codificadas en socket.io, por lo que no puedo bifurcar toda la biblioteca, no puedo cambiarlas.

ChiperSoft
fuente

Respuestas:

39

Use las condiciones de reescritura para que coincidan con 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 anotó a continuación. Estos deben ingresarse a nivel de vhost y no a nivel de servidor o .htaccess.

También puede hacer referencia a un equilibrador:

<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
fuente
+100000 Me alegraste el día. He estado en esto por horas. Usé el primer fragmento de código. No necesito un equilibrador en este momento.
Eamorr
No puedo hacer que esto funcione. Apache sigue respondiendo con un código 404. Aparece en el registro de acceso como si estuviera tratando de cargar un archivo normal, y el proceso del nodo del socket no muestra signos de recibir la solicitud (muestra la llamada para el archivo socket.io.js)
ChiperSoft
1
Parece que mod_rewrite no conoce el protocolo ws: //. Veo esto en mi registro de reescritura: forcing proxy-throughput with http://[REDACTED].dev/ws://localhost:8082/socket.io/(domain.dev
ChiperSoft
Probablemente sea por eso: issues.apache.org/bugzilla/show_bug.cgi?id=55598 Parece que se agregó soporte para el protocolo en Apache 2.5
ChiperSoft
55
NOTA : Estos bloques deben colocarse dentro del <VirtualHost>bloque en el orden exacto descrito, incluso si está utilizando la raíz del documento (por ejemplo /var/www/html). Pasé casi 2 horas tratando de descubrir por qué estos cambios no funcionaban correctamente, solo para descubrir que los RewriteRule's no funcionaban a nivel raíz httpd.conf(aunque sí ProxyPassfuncionaban). Las ProxyPassdirectivas no funcionan en <Directory>bloques o .htaccessarchivos (aunque sí lo RewriteRulehacen), por lo que es el lugar lógico para agrupar estos cambios <VirtualHost>.
Mark W