Question

J'ai un proxy Apache pour une application Meteor et Apache et Meteor sont sur deux machines distinctes.J'en ai besoin car Apache doit servir de nombreux sites Web réels et ce ne serait pas une bonne idée d'installer l'application Meteor sur cette machine en raison de ses ressources limitées.

Cependant, la négociation WebSocket échoue avec le code de réponse 400 « Peut être mis à niveau uniquement vers Websocket » si j'essaie de me connecter de l'extérieur via le proxy.Tout fonctionne bien lorsque je me connecte depuis le réseau local directement à la machine météore.Lorsque WebSocket échoue, SockJS/Meteor revient à XHR mais malheureusement cela entraîne des bugs dans l'application en question.J'ai donc vraiment besoin de WebSocket pour fonctionner dans la plupart des cas.

J'ai corrigé mon installation Apache avec le correctif mentionné ici : https://stackoverflow.com/a/16998664Apparemment, tout s'était bien passé, mais rien n'a changé...

Mes directives proxy Apache sont actuellement les suivantes :

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/

Et je sais même ce qui déclenche le problème.Le proxy Apache joue avec l'en-tête.L'en-tête de requête d'origine du paquet en question quittant ma machine ressemble à ceci :

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

Pendant que le paquet est transféré depuis le proxy Apache comme ceci :

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

Ainsi, "Mise à niveau" est supprimée et "Connexion" modifiée, ce qui entraîne l'échec de la prise de contact Websocket.Maintenant, je pourrais essayer de toujours définir "Upgrade" sur "websocket" avec une directive RequestHeader.Cependant, cela ne semble pas correct et je suppose que cela soulèverait d'autres problèmes. Je me demandais donc s'il existe une véritable solution à ce problème ?Ou est-ce quelque chose que le patch de https://stackoverflow.com/a/16998664 devrais-je l'adresser et quelque chose s'est mal passé de mon côté en l'appliquant ?

D'après ce que j'ai lu, le passage à nginx pourrait faciliter cette configuration.J'y réfléchirai, mais lorsque cela sera possible, j'aimerais le faire avec Apache, car nginx rendrait d'autres choses plus compliquées et me coûterait beaucoup de temps.

Était-ce utile?

La solution

Nous l'utilisons pour Apache et une application SockJS derrière Apache.Apache effectue automatiquement le proxy WebSocket, mais vous devez réécrire le schéma en ws, sinon il revient à XHR.Mais seulement si la connexion est une poignée de main WebSocket.L'ajout de ce qui suit résoudra votre problème :) (remarque :changer la localhost:3000 en fonction de votre propre URL backend.

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

Autres conseils

Cette réponse est basée sur la réponse de Fatih.Sa solution échoue à des navigateurs qui envoient une en-tête de demande de connexion autre que "mise à niveau", telle que "Garder-Alive, mise à niveau".C'était le cas pour moi avec Firefox 42.

Pour résoudre le problème pour Firefox également, modifiez la réécriture Apache comme suit:

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

( ^ ^ Mise à niveau $ devient mise à niveau $ )

Je voulais mettre cela comme un commentaire à la réponse de Fatih, mais je manque la réputation nécessaire.

Après avoir lu plusieurs réponses, affichez sur le Forum de Meteor, et beaucoup d'essais ici sont l'ensemble de l'enchilada qui a fonctionné pour moi.Les autres réponses étaient quelque peu incomplètes ou du moins ne travaillaient pas pour moi.

Je devais faire:

sudo a2enmod proxy_wstunnel 

a également dû ajouter une proxypasse et une mise à niveau ^ ^ $ ^ $ pour mettre à niveau $ à partir d'une autre réponse.

<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>

Redémarrez Apache.

J'ai vérifié sur la console et il n'y a aucune erreur d'erreur et pas de demande XHR.Alors je suppose que cela fonctionne correctement

J'aimerais avoir pu vous fournir une réponse directe avec des instructions Apache, mais que vous avez mentionné NGinx et que le fait est, il est difficile de configurer, je voudrais peser avec une alternative qui utilise réellement NGinx maisvous protège de toutes les complexités.

Le tutoriel à https://github.com/Plusion/Passager / Wiki / Phusion-passager: -Meteor-Tutorial traverse les étapes à suivre pour configurer Passager de la Phusion avec ou sans nginx (il utilise en interne Nginx de toute façon) pour des déploiements de météores de production multi-instance qui peuvent augmenter pour utiliser tous les noyaux de votre serveur.

C'est aussi simple que:

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

La réponse de Fatih-Arslan avec L'amendement de derwiwie a fonctionné comme charme. Une chose que je devais utiliser était de mettre wss au lieu de ws , car mon service ne fonctionne que dans https.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top