Konfigurasi Apache 2.4 mod_proxy_wstunnel untuk Socket.IO 1.0

15

Saya mencoba mengkonfigurasi Apache 2.4 untuk mem-proxy-kan koneksi websocket untuk socket.io ke server websocket node.js, menggunakan mod_proxy_wstunnel. Kami memiliki ini berfungsi dengan baik dengan socket.io 0.9, tetapi dengan rilis 1.0 mereka mengubah soket endpoint menjadi parameter kueri, dan sekarang saya mengalami kesulitan mengkonfigurasi apache dengan instruksi proxy yang benar.

Semua permintaan ke /socket.io/?EIO=N&transport=websocket(di mana N adalah angka berapa pun, biasanya 2) perlu diteruskan ke ws://localhost:8082/socket.io/, tetapi semua permintaan lainnya harus diteruskan ke http://localhost:8082/socket.io/.

Saya sudah mencoba variasi kedua konfigurasi berikut:

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/

Saya telah mengumpulkan dari Google bahwa ProxyPass dan Lokasi tidak dapat menargetkan string kueri, jadi apakah ada opsi lain di sini? Jalur-jalur tersebut dikodekan dengan keras menjadi socket.io, sehingga singkat dari memalsukan seluruh perpustakaan saya tidak dapat mengubahnya.

ChiperSoft
sumber

Jawaban:

39

Gunakan kondisi Menulis ulang yang cocok dengan kasus khusus ini:

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

CATATAN Seperti Mark W catat di bawah ini. Ini harus dimasukkan di tingkat vhost dan bukan di tingkat server atau .htaccess.

Anda juga dapat mereferensikan penyeimbang:

<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
sumber
+100000 Anda membuat hari saya. Sudah berjam-jam di sini. Saya menggunakan potongan kode pertama. Saya tidak membutuhkan penyeimbang saat ini.
Eamorr
Saya tidak bisa menjalankannya. Apache terus merespons dengan kode 404. Itu muncul di log akses seolah-olah sedang mencoba memuat file normal, dan proses socket node tidak menunjukkan tanda-tanda menerima permintaan (itu memang menunjukkan panggilan untuk file socket.io.js)
ChiperSoft
1
Tampaknya mod_rewrite tidak tahu protokol ws: //. Saya melihat ini di log penulisan ulang saya: forcing proxy-throughput with http://[REDACTED].dev/ws://localhost:8082/socket.io/(domain.dev
ChiperSoft
Ini mungkin mengapa: issues.apache.org/bugzilla/show_bug.cgi?id=55598 Sepertinya dukungan untuk protokol ditambahkan di Apache 2.5
ChiperSoft
5
CATATAN : Blok-blok ini harus ditempatkan di dalam <VirtualHost>blok sesuai urutan yang dijelaskan, bahkan jika Anda menggunakan root dokumen (misalnya /var/www/html). Saya menghabiskan hampir 2 jam mencoba mencari tahu mengapa perubahan ini tidak berfungsi dengan baik, hanya untuk mengetahui bahwa RewriteRuleitu tidak berfungsi pada tingkat root httpd.conf(walaupun ProxyPassberfungsi). The ProxyPassarahan tidak bekerja di <Directory>blok atau .htaccessfile (meskipun RewriteRule's lakukan), sehingga tempat yang logis untuk kelompok perubahan ini adalah di <VirtualHost>.
Mark W