Konfigurieren von Apache 2.4 mod_proxy_wstunnel für Socket.IO 1.0

15

Ich versuche, Apache 2.4 so zu konfigurieren, dass die Websocket-Verbindung für socket.io über mod_proxy_wstunnel an einen node.js-Websocket-Server weitergeleitet wird. Wir hatten dieses Problem mit socket.io 0.9, aber mit der Version 1.0 haben sie den Socket-Endpunkt in einen Abfrageparameter geändert, und jetzt habe ich Probleme, Apache mit den richtigen Proxy-Anweisungen zu konfigurieren.

Alle Anfragen an /socket.io/?EIO=N&transport=websocket(wobei N eine Ziffer ist, normalerweise 2) müssen an weitergeleitet werden ws://localhost:8082/socket.io/, aber alle anderen Anfragen müssen an weitergeleitet werden http://localhost:8082/socket.io/.

Ich habe Variationen der beiden folgenden Konfigurationen ausprobiert:

ProxyPass /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket
ProxyPassReverse /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

.

RewriteRule /socket.io/?EIO=([0-9]+)&transport=websocket ws://localhost:8082/socket.io/ [QSA,P]

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

Ich habe durch meine Google-Suche festgestellt, dass ProxyPass und Locations keine Abfragezeichenfolgen ansteuern können. Gibt es hier also eine andere Option? Die Pfade sind fest in socket.io codiert, so dass ich sie nicht ändern kann, wenn ich nicht die gesamte Bibliothek gegabelt habe.

ChiperSoft
quelle

Antworten:

39

Verwenden Sie Rewrite-Bedingungen, um für diesen Sonderfall zu passen:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:8082/$1 [P,L]

ProxyPass        /socket.io http://localhost:8082/socket.io
ProxyPassReverse /socket.io http://localhost:8082/socket.io

ANMERKUNG Wie unten unter W vermerkt. Diese müssen auf vhost-Ebene und nicht auf Server- oder .htaccess-Ebene eingegeben werden.

Sie können auch auf einen Balancer verweisen:

<Proxy balancer://http-localhost/>
    BalancerMember http://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember http://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    ProxySet lbmethod=bytraffic
</Proxy>

<Proxy balancer://ws-localhost/>
    BalancerMember ws://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember ws://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    ProxySet lbmethod=bytraffic
</Proxy>

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io                [NC]
RewriteCond %{QUERY_STRING} transport=websocket        [NC]
RewriteRule /(.*)           balancer://ws-localhost/$1 [P,L]

ProxyPass        /socket.io balancer://http-localhost/socket.io
ProxyPassReverse /socket.io balancer://http-localhost/socket.io
PeterPramb
quelle
+100000 Du hast meinen Tag gemacht. Schon seit Stunden dabei. Ich habe das erste Code-Snippet verwendet. Ich brauche im Moment keinen Balancer.
Eamorr
Ich kann das nicht zum Laufen bringen. Apache antwortet weiterhin mit einem 404-Code. Es wird im Zugriffsprotokoll angezeigt, als würde versucht, eine normale Datei zu laden, und der Socket-Knoten-Prozess zeigt keine Anzeichen für den Empfang der Anforderung an (es wird der Aufruf für die Datei
socket.io.js
1
Es scheint, dass mod_rewrite das ws: // Protokoll nicht kennt. Ich sehe dies in meinem Umschreibeprotokoll: forcing proxy-throughput with http://[REDACTED].dev/ws://localhost:8082/socket.io/(domain.dev
ChiperSoft
Dies ist wahrscheinlich der Grund: issues.apache.org/bugzilla/show_bug.cgi?id=55598 Offenbar wurde das Protokoll in Apache 2.5
ChiperSoft
5
HINWEIS : Diese Blöcke sollten <VirtualHost>in der genau beschriebenen Reihenfolge innerhalb des Blocks platziert werden, auch wenn Sie den Dokumentstamm verwenden (z /var/www/html. B. ). Ich habe fast 2 Stunden damit verbracht herauszufinden, warum diese Änderungen nicht richtig funktionieren, nur um herauszufinden, dass die Änderungen RewriteRulenicht auf der Root-Ebene von funktionieren httpd.conf(obwohl sie ProxyPassfunktionieren). Die ProxyPassDirektiven funktionieren nicht in <Directory>Blöcken oder .htaccessDateien (obwohl dies der RewriteRuleFall ist), daher befindet sich der logische Ort zum Gruppieren dieser Änderungen in <VirtualHost>.
Mark W