Domanda

Ho un proxy Apache per un'app Meteor e Apache e Meteor sono su due macchine separate. Ne ho bisogno in questo modo come Apache deve servire molti siti Web reali e non sarebbe una buona idea installare l'app Meteor su questa macchina a causa delle sue risorse limitate.

Tuttavia, la handshake di Websocket non riesce con il codice di risposta 400 "può aggiornare solo a WebSocket" se provo a connettersi dall'esterno tramite il proxy. Tutto funziona bene quando mi collego all'interno della LAN direttamente alla macchina Meteor. Quando WebSocket fallisce Sockjs / Meteor torna a XHR ma sfortunatamente questo porta alcuni bug nell'app in questione. Quindi ho davvero bisogno di WebSchocket per lavorare nella maggior parte dei casi.

Ho rattoppato la mia installazione Apache con la patch menzionata qui: https://stackoverflow.com/a/16998664 Sembrava che fosse andato bene ma niente è cambiato ...

Le mie direttive proxy Apache attualmente sono le seguenti:

ProxyRequests Off
ProxyPreserveHost On
ModPagespeed Off
<proxy>
Order deny,allow
Allow from all
</proxy>
ProxyPass / http://10.0.2.6:3000/
ProxyPassReverse / http://10.0.2.6:3000/
.

e so ancora cosa attiva il problema. Il proxy Apache si incasinato con l'intestazione. L'intestazione di richiesta originale del pacchetto in questione lasciando la mia macchina sembra questa:

GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent
.

Mentre il pacchetto viene inoltrato da Apache Proxy come questa:

GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent
X-Forwarded-For: 24.xxx.xxx.xxx
X-Forwarded-Host: example.com
X-Forwarded-Server: example.com
Connection: Keep-Alive
.

Quindi "Aggiornamento" viene rimosso e "Connessione" alterata e quindi il handshake WebSocket fallisce. Ora potrei provare a impostare sempre "Aggiorna" a "WebSocket" con una direttiva su richiesta. Tuttavia questo non si sente giusto e immagino che avrebbe portato avanti altri problemi e quindi mi stavo chiedendo se c'è una soluzione reale a questo problema? O è qualcosa che la patch da https://stackoverflow.com/a/16998664 dovrebbe affrontare e qualcosa è andato storto sulla mia fine applicando It?

Da ciò che ho letto che passa a nginx potrebbe semplificare questa configurazione. Lo considererò ma quando possibile mi piacerebbe farlo con Apache come Nginx renderebbe altre cose più complicate e mi costano molto tempo.

È stato utile?

Soluzione

Usiamo questo per Apache e un'app Sockjs dietro Apache.Apache sta facendo automaticamente il proxy WebSocket, ma devi riscrivere lo schema su ws altrimenti fallbacks to xhr.Ma solo se la connessione è una handshake di Websocket.L'aggiunta di quanto segue risolverà il problema :) (Nota: modifica il localhost:3000 di conseguenza del proprio URL di back-end.

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]
.

Altri suggerimenti

Questa risposta è basata sulla risposta di Fatih.La sua soluzione non riesce per i browser che inviano un'intestazione di richiesta di connessione diversa da "Aggiornamento", come "Keep-Alive, Upgrade".Questo è stato il caso per me con Firefox 42.

Per affrontare il problema per Firefox, cambia anche il rewritecond Apache come segue:

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]
.

( ^ Upgrade $ diventa Aggiornamento $ )

Volevo metterlo come un commento alla risposta di Fatih, tuttavia mi manca la reputazione necessaria.

Dopo aver letto diverse risposte, pubblicazione sul forum di Meteor, e un sacco di prove qui è l'intero enchilada che ha funzionato per me.Le altre risposte erano in qualche modo incomplete, o almeno non hanno funzionato per me.

Ho dovuto fare:

sudo a2enmod proxy_wstunnel 
.

ha dovuto anche aggiungere un ProxyPass e ProxyPassReverse e modificato ^ Aggiorna $ per aggiornare $ da un'altra quindi risposta.

<VirtualHost *:80>
    ServerName  some-domain.com

    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]

    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/

</VirtualHost>
.

Quindi riavviare Apache.

Ho controllato la console e non ci sono errori ora e nessuna richiesta XHR.Quindi presumo che funzioni correttamente

Vorrei essere stato in grado di fornirti una risposta diretta con le istruzioni di Apache, ma dal momento che hai menzionato Nginx e che il fatto è, è difficile da configurare, vorrei pesare con un'alternativa che usa effettivamente nginx mati protegge da tutte le complessità.

Il tutorial a https://github.com/phusion/passeggero / wiki / fusione-passeggero: -meteor-tutorial cammina attraverso i passaggi per configurare Passeggero di fusione Con o senza nginx (utilizza comunque nginx internamente) per le distribuzioni di meteori di produzione multi-istanza che possono ridimensionare per utilizzare tutti i nuclei nel server.

È facile come:

$ cd meteor-app-directory
$ mkdir public tmp
$ passenger start
.

Fatih-Arsslan la risposta con Derwiwiwie L'emendamento ha funzionato come fascino. Una cosa che dovevo usare stava mettendo WSS anziché ws , poiché il mio servizio funziona solo in HTTPS.

RewriteEngine on  
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]  
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]  
RewriteRule .* wss://localhost:3000%{REQUEST_URI} [P]
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top