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 Apache2 soit (1) comprendre WebSocket ou (2) simplement transmettre aveuglément tout ce qu'il obtient?
Il y a maintenant un module dans le tronc Apache appelé mod_proxy_wstunnel qui permet à mod_proxy (ProxyPass/ProxyPassReverse) de traverser le trafic WebSocket. Quelqu'un a écrit un article de blog sur back-porting mod_proxy_wstunnel vers Apache 2.4/2.2 et a fourni un correctif pour le faire.
J'ai trouvé concret instructions pour configurer mod_proxy_wstunnel sur Ubunt (testé avec Ubuntu Server 11.10 et Apache 2.2.20) et les ai postés sur mon blog. Je les ai copiés ci-dessous:
# 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
Il y a rien à indiquer Apache httpd les supportera de sitôt.
Si vous devez exécuter des websockets via Apache, essayez mod_pywebsocket . Je l'ai essayé et ça marche.
Voici quelques alternatives que je préfère:
On dirait qu'avec une combinaison du plugin de déconnexion et du code supplémentaire, cela est maintenant possible:
http://blog.alex.org.uk/2012/02/16/using-Apache-websocket-to-proxy-tcp-connection/
Veuillez jeter un œil à http://github.com/disconnect/Apache-websocket
Le module Apache-websocket est un module serveur Apache 2.x qui peut être utilisé pour traiter les demandes utilisant le protocole WebSocket par un serveur Apache 2.x.
Cet ajout à @ Andrew Moss 'répond à la façon de configurer correctement le VirtualHost
pour qu'il fonctionne 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 (soit clonez le Gist, soit téléchargez les fichiers individuellement)yum install make gcc httpd-devel
.c
- fichier dans le sous-dossier SOURCES
de l'environnement et le .spec
- fichier dans le sous-dossier SPECS
.rpmbuild -ba mod_proxy_wstunnel.spec
SRPMS
rpm -i /path/to/package.rpm
Cela chargera également automatiquement le module dans Apache, il vous suffit donc de le redémarrer avec service httpd restart
.
Configuration d'un VirtualHost
pour réellement servir le serveur Socket.io et le script client (qui est par défaut disponible sous http://your.server/socket.io/socket.io.js
) est un peu plus compliqué sur Apache 2.2, à cause d'un Bug dans le mod_proxy
module :
Étant donné la règle de réécriture suivante:
RewriteRule ^/ws(.*)$ ws://localhost:9000/ws [P]
mod_rewrite
traite cela comme un chemin de fichier afin que le journal d'accès affiche:[26/Sep/2013:09:46:07 -0400] "GET /ws://localhost:9000/ws HTTP/1.1" 400 317
Donc, vous ne pouvez pas utiliser le protocole ws
- dans une règle de réécriture , car cela se transformera en interne en une requête HTTP GET .
Il existe cependant une solution:
<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.io
va au ws://
- protocole, à l'exception de la demande d'interrogation longue (qui est un mécanisme de secours lorsque les WebSockets ne sont pas disponibles) et de la demande de la bibliothèque cliente.