pass node.js apache proxy websocket socket.io

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.

  1. Habilite las siguientes modificaciones de Apache2:

    sudo a2enmod proxy rewrite proxy_http proxy_wstunnel

  2. 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>

  3. 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 :

  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 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:

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

  2. 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 Tomcat

    ws://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/"