WebSockets y proxy Apache: cómo configurar mod_proxy_wstunnel?

Yo tengo :

  1. Apache (v2.4) en el puerto 80 de mi servidor para www.domain1.com , con mod_proxy y mod_proxy_wstunnel habilitado

  2. node.js + socket.io en el puerto 3001 del mismo servidor.

El acceso a www.domain2.com (con el puerto 80) redirige a 2. gracias al método que se describe aquí . Lo he configurado en la configuración de Apache:

  ServerName www.domain2.com ProxyPass / http://localhost:3001/ ProxyPassReverse / http://localhost:3001/ ProxyPass / ws://localhost:3001/ ProxyPassReverse / ws://localhost:3001/  

Funciona para todo, excepto la parte websocket: ws://... no se transmiten como debería por el proxy.

Cuando www.domain2.com la página en www.domain2.com , tengo:

 Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN. 

Pregunta: ¿Cómo hacer que Apache proxy sea también WebSockets?

Finalmente logré hacerlo, gracias a este tema .

QUE HACER:

1) Tener instalado Apache 2.4 (no funciona con 2.2), y hacer:

 a2enmod proxy a2enmod proxy_http a2enmod proxy_wstunnel 

2) Tener nodejs ejecutándose en el puerto 3001

3) Haz esto en la configuración de Apache

  ServerName www.domain2.com RewriteEngine On RewriteCond %{REQUEST_URI} ^/socket.io [NC] RewriteCond %{QUERY_STRING} transport=websocket [NC] RewriteRule /(.*) ws://localhost:3001/$1 [P,L] ProxyPass / http://localhost:3001/ ProxyPassReverse / http://localhost:3001/  

Nota: si tiene más de un servicio en el mismo servidor que usa websockets, es posible que desee hacer esto para separarlos.

En lugar de filtrar por URL, también puede filtrar por encabezado HTTP. Esta configuración funcionará para cualquier aplicación web que use websockets, también si no están usando socket.io:

  ServerName www.domain2.com RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /(.*) ws://localhost:3001/$1 [P,L] RewriteCond %{HTTP:Upgrade} !=websocket [NC] RewriteRule /(.*) http://localhost:3001/$1 [P,L] ProxyPassReverse / http://localhost:3001/  

Puede ser será útil. Todas las consultas se envían a través de ws al nodo

  ServerName www.domain2.com  ProxyPass "ws://localhost:3001/"   

A partir de Socket.IO 1.0 (mayo de 2014), todas las conexiones comienzan con una solicitud de sondeo HTTP (más información aquí ). Eso significa que, además de reenviar el tráfico de WebSocket, debe reenviar cualquier transport=polling solicitudes HTTP.

La siguiente solución debe redirigir todo el tráfico del socket correctamente, sin redirigir ningún otro tráfico.

  1. Habilite los siguientes mods de Apache2:

     sudo a2enmod proxy rewrite proxy_http proxy_wstunnel 
  2. Use estas configuraciones en su archivo * .conf (por ejemplo, /etc/apache2/sites-available/mysite.com.conf ). He incluido comentarios para explicar cada pieza:

      ServerName www.mydomain.com # Enable the rewrite engine # Requires: sudo a2enmod proxy rewrite proxy_http proxy_wstunnel # In the rules/conds, [NC] means case-insensitve, [P] means proxy RewriteEngine On # socket.io 1.0+ starts all connections with an HTTP polling request RewriteCond %{QUERY_STRING} transport=polling [NC] RewriteRule /(.*) http://localhost:3001/$1 [P] # When socket.io wants to initiate a WebSocket connection, it sends an # "upgrade: websocket" request that should be transferred to ws:// RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /(.*) ws://localhost:3001/$1 [P] # OPTIONAL: Route all HTTP traffic at /node to port 3001 ProxyRequests Off ProxyPass /node http://localhost:3001 ProxyPassReverse /node http://localhost:3001  
  3. He incluido una sección adicional para el tráfico de enrutamiento /node que encuentro útil, mira aquí para más información.

Mi configuración:

Apache 2.4.10 (ejecutando Debian) NodeJS (versión 4.1.1) Aplicación ejecutándose en el puerto 3000 que acepta WebSockets en path / api / ws

Como se mencionó anteriormente por @Basj, asegúrese de que a2enmod proxy y ws_tunnel estén habilitados.

Esta es una captura de pantalla del archivo Apache conf que resolvió mi problema:

enter image description here

Espero que ayude.

Con la ayuda de estas respuestas, finalmente obtuve el proxy inverso para Node-RED ejecutándose en una Raspberry Pi con Ubuntu Mate y Apache2 trabajando, usando esta configuración de sitio Apache2:

  ServerName nodered.domain.com RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /(.*) ws://localhost:1880/$1 [P,L] RewriteCond %{HTTP:Upgrade} !=websocket [NC] RewriteRule /(.*) http://localhost:1880/$1 [P,L]  

También tuve que habilitar módulos como este:

 sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_wstunnel 

Para mí funciona después de agregar solo una línea en httpd.conf como a continuación (línea en negrita).

  ServerName: xxxxx #ProxyPassReverse is not needed ProxyPass /log4j ws://localhost:4711/logs  

La versión de Apache es 2.4.6 en CentOS.

Para el transporte de “sondeo”.

Lado de Apache:

  ServerName mysite.com DocumentRoot /my/path ProxyRequests Off  Order deny,allow Allow from all  ProxyPass /my-connect-3001 http://127.0.0.1:3001/socket.io ProxyPassReverse /my-connect-3001 http://127.0.0.1:3001/socket.io  

Lado del cliente:

 var my_socket = new io.Manager(null, { host: 'mysite.com', path: '/my-connect-3001' transports: ['polling'], }).socket('/'); 

Usuario de este enlace para la solución perfact para ws https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

Solo tienes que hacer el paso inferior …

Llegué a / etc / apache2 / mods-available

Paso 1

Habilite el modo proxy_wstunnel.load usando el comando debajo

$ a2enmod proxy_wstunnel.load

Paso 2

Ir a / etc / apache2 / sites-available

y agregue la línea siguiente en su archivo .conf dentro del host virtual

ProxyPass “/ ws2 /” “ws: // localhost: 8080 /”

ProxyPass “/ wss2 /” “wss: // localhost: 8080 /”

Nota: 8080 significa que es el puerto en el que se ejecuta tomcat porque queremos conectar “ws”, donde nuestro archivo de Guerra está en “tomcat” y “tomcat” en “apache” para “ws”. gracias

Mi configuración

ws: //localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver? userid = 4 = Conectado

QUE HACER:

  1. Tener Apache 2.4 instalado (no funciona con 2.2), a2enmod proxy a2enmod proxy_wstunnel.load y a2enmod proxy_wstunnel.load

  2. Haz esto en la configuración de Apache
    solo agregue dos líneas en su archivo donde 8080 es su puerto de ejecución tomcat

      ProxyPass "/ws2/" "ws://localhost:8080/" ProxyPass "/wss2/" "wss://localhost:8080/"  

Además de la respuesta principal: si tiene más de un servicio en el mismo servidor que usa websockets, puede hacer esto para separarlos, utilizando una ruta personalizada (*):

Servidor de nodo:

 var io = require('socket.io')({ path: '/ws_website1'}).listen(server); 

Cliente HTML:

  ...  

Configuración de Apache:

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

(*) Nota: el uso de RewriteCond %{REQUEST_URI} ^/socket.io predeterminado RewriteCond %{REQUEST_URI} ^/socket.io no sería específico de un sitio web, ¡y las solicitudes de websockets se mezclarían entre diferentes sitios web!

Hizo lo siguiente para una aplicación de spring que ejecuta contenido estático, de descanso y de websocket.

Apache se usa como Proxy y punto final SSL para los siguientes URI:

  • / app → contenido estático
  • / api → API REST
  • / api / ws → websocket

Configuración de Apache

  ServerName xxx.xxx.xxx ProxyRequests Off ProxyVia Off ProxyPreserveHost On  Require all granted  RewriteEngine On # websocket RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule ^/api/ws/(.*) ws://localhost:8080/api/ws/$1 [P,L] # rest ProxyPass /api http://localhost:8080/api ProxyPassReverse /api http://localhost:8080/api # static content ProxyPass /app http://localhost:8080/app ProxyPassReverse /app http://localhost:8080/app  

Utilizo la misma configuración vHost para la configuración SSL, no es necesario cambiar nada relacionado con el proxy.

Configuración de spring

 server.use-forward-headers: true