J'ai :
Apache
(v2.4) sur le port 80 de mon serveur pour www.domain1.com
, avec mod_proxy et mod_proxy_wstunnelactivé
node.js + socket.io
sur le port 3001 du même serveur.
Accéder à www.domain2.com
(avec le port 80) redirige en 2. grâce à la méthode décrite ici . J'ai mis cela dans la configuration d'Apache:
<VirtualHost *:80>
ServerName www.domain2.com
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPass / ws://localhost:3001/
ProxyPassReverse / ws://localhost:3001/
</VirtualHost>
Cela fonctionne pour tout, sauf la partie websocket: ws://...
ne sont pas transmis comme il se doit par le proxy.
Lorsque j'accède à la page sur www.domain2.com
, j'ai:
Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.
Question: Comment faire du proxy Apache les WebSockets?
J'ai finalement réussi à le faire, grâce à ce sujet .
FAIRE:
1) Avoir Apache 2.4 installé (ne fonctionne pas avec 2.2), et faites:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
2) Avoir nodejs
exécuté sur le port 3001
3) Faites ceci dans la configuration 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>
Remarque: si plusieurs services sur le même serveur utilisent des websockets, vous souhaiterez peut-être faire ceci pour les séparer.
Au lieu de filtrer par URL, vous pouvez également filtrer par en-tête HTTP. Cette configuration fonctionnera pour toutes les applications Web utilisant des websockets, même si elles n'utilisent pas 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>
Peut-être sera-t-il utile… .. Toutes les requêtes sont envoyées via ws au noeud
<VirtualHost *:80>
ServerName www.domain2.com
<Location "/">
ProxyPass "ws://localhost:3001/"
</Location>
</VirtualHost>
Depuis Socket.IO 1.0 (mai 2014), toutes les connexions commencent par une demande d'interrogation HTTP (plus d'infos ici ). Cela signifie qu'en plus du transfert du trafic WebSocket, vous devez également transférer les requêtes HTTP transport=polling
.
La solution ci-dessous devrait rediriger correctement tout le trafic de socket, sans rediriger tout autre trafic.
Activez les mods Apache2 suivants:
Sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
Utilisez ces paramètres dans votre fichier * .conf (par exemple, /etc/Apache2/sites-available/mysite.com.conf
). J'ai inclus des commentaires pour expliquer chaque pièce:
<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>
J'ai inclus une section supplémentaire pour le routage du trafic /node
que je trouve pratique, voir ici pour plus d'informations.
Avec l'aide de ces réponses, j'ai finalement obtenu le proxy inverse pour Node-RED s'exécutant sur un Raspberry Pi avec Ubuntu Mate et Apache2, en utilisant cette configuration de site 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>
Je devais aussi activer des modules comme celui-ci:
Sudo a2enmod proxy
Sudo a2enmod proxy_http
Sudo a2enmod proxy_wstunnel
Ma configuration:
Apache 2.4.10 (sous Debian) NodeJS (version 4.1.1) Application fonctionnant sur le port 3000 acceptant WebSockets sur chemin/api/ws
Comme mentionné ci-dessus par @Basj, assurez-vous que les proxy a2enmod et ws_tunnel sont activés.
Ceci est une capture d'écran du fichier de configuration Apache qui a résolu mon problème:
J'espère que cela pourra aider.
Faites ce qui suit pour une application de printemps exécutant du contenu statique, repos et websocket.
Apache est utilisé comme point de terminaison proxy et SSL pour les URI suivants:
<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>
J'utilise la même configuration vHost pour la configuration SSL, pas besoin de changer quoi que ce soit lié au proxy.
server.use-forward-headers: true
Pour moi, cela fonctionne après avoir ajouté une seule ligne dans httpd.conf comme ci-dessous (ligne en gras).
<VirtualHost *:80>
ServerName: xxxxx
#ProxyPassReverse is not needed
ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>
La version d'Apache est 2.4.6 sur CentOS.
En plus de la réponse principale: si vous avez plusieurs services sur le même serveur qui utilise Websockets, vous pouvez le faire pour les séparer, en utilisant un chemin personnalisé (*). :
Serveur de nœud:
var io = require('socket.io')({ path: '/ws_website1'}).listen(server);
Client HTML:
<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('', { path: '/ws_website1' });
...
Apache config:
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]
(*) Remarque: l'utilisation de la valeur par défaut RewriteCond %{REQUEST_URI} ^/socket.io
ne serait pas spécifique à un site Web et les demandes de Websockets seraient mélangées entre différents sites Web!
Pour le transport "polling".
Côté Apache:
<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>
Côté client:
var my_socket = new io.Manager(null, {
Host: 'mysite.com',
path: '/my-connect-3001'
transports: ['polling'],
}).socket('/');
FAIRE:
Avoir Apache 2.4 installé (ne fonctionne pas avec 2.2), a2enmod proxy
et a2enmod proxy_wstunnel.load
Faites cela dans la configuration Apache
il suffit d’ajouter deux lignes dans votre fichier où 8080 est votre port d’exécution Tomcat
<VirtualHost *:80>
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
</VirtualHost *:80>
Utilisez ce lien pour une solution parfaite pour ws https://httpd.Apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
Vous devez juste faire ci-dessous l'étape ..
Arrivé à/etc/Apache2/mods-available
Étape 1
Activer le mode proxy_wstunnel.load en utilisant la commande ci-dessous
$ a2enmod proxy_wstunnel.load
Étape 2
Aller à/etc/Apache2/sites-available
et ajoutez la ligne ci-dessous dans votre fichier .conf à l'intérieur de l'hôte virtuel
ProxyPass "/ ws2 /" "ws: // localhost: 8080 /"
ProxyPass "/ wss2 /" "wss: // localhost: 8080 /"
Remarque: 8080 signifie que votre port Tomcat est en cours d'exécution parce que nous voulons connecter "ws", où notre fichier War mis dans Tomcat et Tomcat servent Apache pour "ws" . Merci
Ma configuration
ws: //localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver? userid = 4 = Connecté