Pregunta

Tengo un proxy Apache para una aplicación Meteor y Apache y Meteor están en dos máquinas separadas.Lo necesito así ya que Apache tiene que servir a muchos sitios web reales y no sería una buena idea instalar la aplicación Meteor en esta máquina debido a sus recursos limitados.

Sin embargo, el protocolo de enlace de WebSocket falla con el código de respuesta 400 "Solo se puede actualizar a websocket" si intento conectarme desde el exterior a través del proxy.Todo funciona bien cuando me conecto desde la LAN directamente a la máquina de meteoritos.Cuando WebSocket falla, SockJS/Meteor vuelve a XHR pero desafortunadamente esto genera algunos errores en la aplicación en cuestión.Entonces realmente necesito que WebSocket funcione en la mayoría de los casos.

Parché mi instalación de Apache con el parche mencionado aquí: https://stackoverflow.com/a/16998664Parecía que todo iba bien pero nada cambió...

Mis directivas de proxy de Apache actualmente son las siguientes:

ProxyRequests Off
ProxyPreserveHost On
ModPagespeed Off
<proxy>
Order deny,allow
Allow from all
</proxy>
ProxyPass / http://10.0.2.6:3000/
ProxyPassReverse / http://10.0.2.6:3000/

E incluso sé qué está provocando el problema.El proxy de Apache se mete con el encabezado.El encabezado de solicitud original del paquete en cuestión que sale de mi máquina se ve así:

GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent

Mientras que el paquete se reenvía desde el proxy Apache de esta manera:

GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent
X-Forwarded-For: 24.xxx.xxx.xxx
X-Forwarded-Host: example.com
X-Forwarded-Server: example.com
Connection: Keep-Alive

Por lo tanto, se elimina "Actualización" y se modifica "Conexión", por lo que falla el protocolo de enlace de websocket.Ahora podría intentar configurar siempre "Actualizar" en "websocket" con una directiva RequestHeader.Sin embargo, esto no me parece correcto y supongo que plantearía otros problemas, por lo que me preguntaba si existe una solución real a este problema.¿O es algo del parche https://stackoverflow.com/a/16998664 debería abordar y algo salió mal por mi parte al aplicarlo?

Por lo que he leído, cambiar a nginx podría facilitar esta configuración.Consideraré esto, pero cuando sea posible me gustaría hacerlo con Apache ya que nginx complicaría otras cosas y me costaría mucho tiempo.

¿Fue útil?

Solución

Usamos esto para Apache y una aplicación SockJS detrás de Apache.Apache está haciendo el proxy WebSocket automáticamente, pero debe reescribir el esquema en ws, de lo contrario, recurrirá a XHR.Pero sólo si la conexión es un protocolo de enlace WebSocket.Agregar lo siguiente solucionará su problema :) (nota:cambiar el localhost:3000 de acuerdo con su propia URL de backend.

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]

Otros consejos

Esta respuesta se basa en la respuesta de Fatih.Su solución falla a los navegadores que envían un encabezado de solicitud de conexión que no sea "Actualización", como "Mantener vivo, actualización".Este fue el caso para mí con Firefox 42.

Para abordar el problema para Firefox también, cambie el APACHE REWITECOND de la siguiente manera:

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]

( ^ actualización $ se convierte en una actualización $ )

Quería poner esto como un comentario a la respuesta de Fatih, sin embargo, me falta la reputación necesaria.

Después de leer varias respuestas, publicar en el foro de meteoritos, y muchas pruebas aquí es toda la enchilada que funcionó para mí.Las otras respuestas fueron algo incompletas, o al menos no funcionaron para mí.

tuve que hacer:

sudo a2enmod proxy_wstunnel 

También tuvo que agregar un proxysass y proxyspassreverse y cambiar ^ actualizar $ para actualizar $ de otra persona.

<VirtualHost *:80>
    ServerName  some-domain.com

    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]

    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/

</VirtualHost>

Luego reinicie Apache.

Revisé la consola y no hay un error ahora y no hay solicitudes de XHR.Así que asumo que está funcionando correctamente

Ojalá pudiera proporcionarle una respuesta directa con las instrucciones directas con las instrucciones de Apache, pero ya que ha mencionado a Nginx y que el hecho es que es difícil configurar, me gustaría pesar con una alternativa que realmente usa NGINX, peroLo protege de todas las complejidades.

El tutorial en https://github.com/phusion/Pasajero / Wiki / Phusing-Passenger: -Meteor-tutorial camina a través de los pasos para configurar Phuser Passenger con o sin nginx (utiliza internamente nginx de todos modos) para implementaciones de meteoros de producción de varias instancias que pueden escalar para utilizar todos los núcleos en su servidor.

Es tan fácil como:

$ cd meteor-app-directory
$ mkdir public tmp
$ passenger start

Respuesta de Fatih-Arslan con La enmienda de Derwiwie funcionó como encanto. Una cosa que tuve que usar fue poner wss en lugar de ws , porque mi servicio funciona solo en https.

RewriteEngine on  
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]  
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]  
RewriteRule .* wss://localhost:3000%{REQUEST_URI} [P]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top