Le protocole WebSocket est une extension du protocole HTTP. Cependant, le module proxy d'Apache2 ne semble pas le savoir et jette les en-têtes cruciaux, convertissant l'appel en un appel HTTP standard.
Existe-t-il un moyen de faire en sorte qu'Apache2 (1) comprenne WebSocket ou (2) transmette tout simplement aveuglément ce qu'il obtient?
Il existe maintenant un module dans le tronc Apache appelé mod_proxy_wstunnel qui permet à mod_proxy (ProxyPass / ProxyPassReverse) de transiter par le trafic WebSocket. Quelqu'un a écrit un article sur le portage de mod_proxy_wstunnel vers Apache 2.4 / 2.2 et a fourni un correctif pour le faire.
# Check apache version (should be 2.2.20 as of writing, if not adjust the next step)
dpkg -s apache2
# Checkout apache source
svn checkout http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20
# Get patch and apply it
wget http://cafarelli.fr/gentoo/apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../apache-2.2.24-wstunnel.patch
# Build Apache
svn co http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x srclib/apr
svn co http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x srclib/apr-util
./buildconf
./configure --enable-proxy=shared --enable-proxy_wstunnel=shared
make
# Copy the module and recompiled mod_proxy (for new symbols) to the ubuntu apache installation and update the permissions to match the other modules
sudo cp modules/proxy/.libs/mod_proxy{_wstunnel,}.so /usr/lib/apache2/modules/
sudo chmod 644 /usr/lib/apache2/modules/mod_proxy{_wstunnel,}.so
echo -e "# Depends: proxy\nLoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so" | sudo tee -a /etc/apache2/mods-available/proxy_wstunnel.load
# Enable the module (also make any configuration changes you need)
sudo a2enmod proxy_wstunnel
sudo service apache2 restart
Quand j'ai suivi votre guide, il y avait une étape que vous n'aviez pas. Après avoir effectué les vérifications après, je devais exécuter ./buildconfigpour créer le fichier de configuration. Et il y avait quelques dépendances qu'il m'a dit d'installer.
notbad.jpeg
Est-ce que cela connecte avec Glassfish 4 sur wss: (SSL)
Archimedes Trajano
1
@ notbad.jpeg: Vous voulez probablement dire ./buildconf (pas ./buildconfig) :-)
Erik Forsberg
1
Juste mes commentaires ... ceci a été installé et chargé dans Apache 2.2.22-1ubuntu1.10 d'Ubuntu 12.04, mais cela n'a pas fonctionné pour moi à la fin. Le proxy supprimait l'en-tête "Upgrade" (le code source indique "RFC2616 13.5.1 indique que nous devrions effacer ces en-têtes"), qui est un en-tête attendu par le serveur, pas seulement un saut, il n'a donc pas fonctionné, et je l'ai remplacé par une règle iptables DNAT à la place.
Peter
11
Rien n'indique qu'Apache httpd les supportera bientôt.
Si vous devez exécuter websockets via Apache, essayez mod_pywebsocket . Je l'ai essayé et ça marche.
Voici quelques alternatives que je préfère:
servir des websockets sur un autre port, en évitant le httpd Apache.
Le module apache-websocket est un module de serveur Apache 2.x qui peut être utilisé pour traiter des requêtes utilisant le protocole WebSocket par un serveur Apache 2.x.
J'ai regardé le projet ci-dessus github. Il n'agit pas en tant que proxy. citationThe module consists of a plugin architecture ...
guettli
1
Ceci est ajouté à la réponse de @Andrew Moss sur la manière de configurer correctement le VirtualHostfonctionnement avec socket.io 1.0! N'hésitez pas à sauter la partie sur CentOS!
Si vous êtes bloqué sur CentOS 6, voici comment procéder:
Téléchargez le code source du mod_proxy_wstunnelmodule ici (clonez le Gist ou téléchargez les fichiers individuellement).
Installez tout le nécessaire pour construire: yum install make gcc httpd-devel
Copiez le .cfichier -file dans le SOURCESsous - dossier de l'environnement et le .specfichier -file dans le SPECSsous - dossier.
Courir rpmbuild -ba mod_proxy_wstunnel.spec
Le paquet est maintenant dans le SRPMSsous - dossier
Installez le paquet: rpm -i /path/to/package.rpm
Profit
Cela chargera aussi automatiquement le module dans Apache, il ne vous reste donc plus qu’à le redémarrer service httpd restart.
Configurer VirtualHostpour servir réellement le serveur Socket.io et le script client (qui est disponible par défaut sous http://your.server/socket.io/socket.io.js) est un peu plus compliqué sur Apache 2.2, à cause d'un bogue dans le mod_proxymodule :
Étant donné la règle de réécriture suivante:
RewriteRule ^/ws(.*)$ ws://localhost:9000/ws [P]
mod_rewrite traite ce chemin comme un fichier afin que le journal des accès montre:
Donc, vous ne pouvez pas utiliser le wsprotocole -protoc dans une règle de réécriture , car cela se transformerait en interne en une requête HTTP GET.
Il existe cependant une solution de contournement:
<VirtualHost *:80>
ServerName your.server
# Proxy socket.io Websocket
RewriteEngine On
# socket.io 1.0+ starts all connections with an HTTP polling request
RewriteCond %{QUERY_STRING} transport=polling [NC]
RewriteRule /(.*) http://localhost:8081/$1 [P]
ProxyRequests Off
# Explicitly send the request for the client-script to HTTP:
ProxyPass /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
ProxyPassReverse /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
# Anything else goes to the WebSocket protocol:
ProxyPass /socket.io/ ws://localhost:8081/socket.io/
ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/
# Any additional stuff (the actual site) comes here
ProxyPass / http://localhost:8081/
ProxyPassReverse / http://localhost:8081/
</VirtualHost>
Cela garantit que tout ce qui est envoyé /socket.iova au ws://protocole, à l'exception de la demande d'interrogation longue (qui est un mécanisme de secours lorsque WebSockets n'est pas disponible) et de la demande de la bibliothèque client.
./buildconfig
pour créer le fichier de configuration. Et il y avait quelques dépendances qu'il m'a dit d'installer.Rien n'indique qu'Apache httpd les supportera bientôt.
Si vous devez exécuter websockets via Apache, essayez mod_pywebsocket . Je l'ai essayé et ça marche.
Voici quelques alternatives que je préfère:
la source
On dirait qu'avec une combinaison du plugin disconnect et du code supplémentaire, cela est maintenant possible:
http://blog.alex.org.uk/2012/02/16/using-apache-websocket-to-proxy-tcp-connection/
la source
S'il vous plaît jeter un oeil à http://github.com/disconnect/apache-websocket
la source
The module consists of a plugin architecture ...
Ceci est ajouté à la réponse de @Andrew Moss sur la manière de configurer correctement le
VirtualHost
fonctionnement avec socket.io 1.0! N'hésitez pas à sauter la partie sur CentOS!Si vous êtes bloqué sur CentOS 6, voici comment procéder:
mod_proxy_wstunnel
module ici (clonez le Gist ou téléchargez les fichiers individuellement).yum install make gcc httpd-devel
.c
fichier -file dans leSOURCES
sous - dossier de l'environnement et le.spec
fichier -file dans leSPECS
sous - dossier.rpmbuild -ba mod_proxy_wstunnel.spec
SRPMS
sous - dossierrpm -i /path/to/package.rpm
Cela chargera aussi automatiquement le module dans Apache, il ne vous reste donc plus qu’à le redémarrer
service httpd restart
.Configurer
VirtualHost
pour servir réellement le serveur Socket.io et le script client (qui est disponible par défaut soushttp://your.server/socket.io/socket.io.js
) est un peu plus compliqué sur Apache 2.2, à cause d'un bogue dans lemod_proxy
module :Donc, vous ne pouvez pas utiliser le
ws
protocole -protoc dans une règle de réécriture , car cela se transformerait en interne en une requête HTTP GET.Il existe cependant une solution de contournement:
Cela garantit que tout ce qui est envoyé
/socket.io
va auws://
protocole, à l'exception de la demande d'interrogation longue (qui est un mécanisme de secours lorsque WebSockets n'est pas disponible) et de la demande de la bibliothèque client.la source