node.js - pass - WebSockets y Apache proxy: ¿cómo configurar mod_proxy_wstunnel?
apache2 websocket (12)
A partir de Socket.IO 1.0 (mayo de 2014), todas las conexiones comienzan con una solicitud de sondeo HTTP (más información
here
).
Eso significa que, además de reenviar el tráfico de WebSocket, debe reenviar cualquier solicitud HTTP de
transport=polling
.
La solución a continuación debe redirigir todo el tráfico de socket correctamente, sin redirigir ningún otro tráfico.
-
Habilite las siguientes modificaciones de Apache2:
sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
-
Use esta configuración en su archivo * .conf (por ejemplo,
/etc/apache2/sites-available/mysite.com.conf
). He incluido comentarios para explicar cada pieza:<VirtualHost *:80> 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 </VirtualHost>
-
He incluido una sección adicional para el enrutamiento
/node
tráfico de/node
que encuentro útil, consulte here para obtener más información.
Yo tengo :
-
Apache
(v2.4) en el puerto 80 de mi servidor parawww.domain1.com
, con mod_proxy y mod_proxy_wstunnel habilitado -
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 descrito aquí
.
He configurado esto en la configuración de Apache:
<VirtualHost *:80>
ServerName www.domain2.com
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPass / ws://localhost:3001/
ProxyPassReverse / ws://localhost:3001/
</VirtualHost>
Funciona para todo, excepto la parte websocket:
ws://...
no se transmite 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 el proxy Apache también sea el WebSockets?
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 nodos:
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]
HTML del cliente:
<VirtualHost *:80>
ServerName mysite.com
DocumentRoot /my/path
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /my-connect-3001 http://127.0.0.1:3001/socket.io
ProxyPassReverse /my-connect-3001 http://127.0.0.1:3001/socket.io
</VirtualHost>
Configuración de Apache:
var my_socket = new io.Manager(null, {
host: ''mysite.com'',
path: ''/my-connect-3001''
transports: [''polling''],
}).socket(''/'');
(*) Nota: el uso de
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.
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 funcionando, usando esta configuración del sitio Apache2:
<VirtualHost *:80>
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]
</VirtualHost>
También tuve que habilitar módulos como este:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
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:
<VirtualHost *:80>
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/
</VirtualHost>
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
<VirtualHost *:80>
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/
</VirtualHost>
Nota: si tiene más de un servicio en el mismo servidor que usa websockets, puede hacer esto para separarlos.
Hice lo siguiente para una aplicación de primavera que ejecuta contenido estático, de descanso y websocket.
Apache se utiliza como Proxy y SSL Endpoint para los siguientes URI:
- / app → contenido estático
- / api → API REST
- / api / ws → websocket
Configuración de Apache
<VirtualHost *:80>
ServerName xxx.xxx.xxx
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
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
</VirtualHost>
Utilizo la misma configuración de vHost para la configuración SSL, no es necesario cambiar nada relacionado con el proxy.
Configuración de primavera
server.use-forward-headers: true
Mi configuración:
- Apache 2.4.10 (ejecutando Debian)
-
Node.js (versión 4.1.1) Aplicación que se ejecuta en el puerto 3000 que acepta WebSockets en la ruta
/api/ws
Como se mencionó anteriormente por @Basj, asegúrese de que el proxy a2enmod y ws_tunnel estén habilitados.
Esta es una captura de pantalla del archivo de configuración de Apache que resolvió mi problema:
La parte relevante como texto:
<VirtualHost *:80>
ServerName *******
ServerAlias *******
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
<Location "/api/ws">
ProxyPass "ws://localhost:3000/api/ws"
</Location>
</VirtualHost>
Espero que ayude.
Para el transporte de "sondeo".
Lado apache:
var io = require(''socket.io'')({ path: ''/ws_website1''}).listen(server);
Lado del cliente:
<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('''', { path: ''/ws_website1'' });
...
Para mí funciona después de agregar solo una línea en httpd.conf como se muestra a continuación (línea en negrita).
<VirtualHost *:80>
ServerName: xxxxx
#ProxyPassReverse is not needed
ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>
La versión de Apache es 2.4.6 en CentOS.
Puede ser será útil. Solo todas las consultas se envían a través de ws al nodo
<VirtualHost *:80>
ServerName www.domain2.com
<Location "/">
ProxyPass "ws://localhost:3001/"
</Location>
</VirtualHost>
QUE HACER:
-
Tener instalado Apache 2.4 (no funciona con 2.2),
a2enmod proxy
ya2enmod proxy_wstunnel.load
-
Haga esto en la configuración de Apache
simplemente agregue dos líneas en su archivo donde 8080 es su puerto de ejecución de Tomcatws://localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver?userid=4 =Connected
Utilice este enlace para obtener una solución perfecta para w mod_proxy_wstunnel
Solo tienes que hacer debajo del paso ...
Vaya a
/etc/apache2/mods-available
Paso 1
Habilite el
mode proxy_wstunnel.load
utilizando el siguiente comando
<VirtualHost *:80>
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
</VirtualHost *:80>
Paso 2
Vaya a
/etc/apache2/sites-available
y agregue la siguiente línea en su archivo .conf dentro del host virtual
$a2enmod proxy_wstunnel.load
Nota: 8080 significa que es su puerto de ejecución de Tomcat porque queremos conectar
ws
donde nuestro archivo War colocado en tomcat y tomcat sirve apache para
ws
.
gracias
Mi configuracion
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"