9

meteor アプリ用の apache プロキシがあり、apache と meteor は 2 つの別々のマシンにあります。apache は多くの実際の Web サイトにサービスを提供する必要があり、リソースが限られているため、このマシンに meteor アプリをインストールすることはお勧めできません。

ただし、プロキシ経由で外部から接続しようとすると、WebSocket ハンドシェイクは応答コード 400「WebSocket にのみアップグレードできます」で失敗します。LAN 内から meteor マシンに直接接続すると、すべて正常に動作します。WebSocket が失敗すると、SockJS/Meteor は XHR にフォールバックしますが、残念ながら、問題のアプリにいくつかのバグが発生します。したがって、ほとんどの場合、WebSocket が機能する必要があります。

ここに記載されているパッチを使用してApacheのインストールにパッチを適用しました:https://stackoverflow.com/a/16998664 うまくいったように見えましたが、何も変わりませんでした...

現在、私のApacheプロキシディレクティブは次のとおりです。

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/

そして、何が問題を引き起こしているのかさえわかっています。Apache プロキシがヘッダーをいじります。私のマシンを離れる問題のパケットの元の要求ヘッダーは次のようになります。

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

パケットは次のように Apache プロキシから転送されます。

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

したがって、「アップグレード」が削除され、「接続」が変更されるため、websocket ハンドシェイクが失敗します。これで、RequestHeader ディレクティブを使用して、常に「アップグレード」を「websocket」に設定しようとすることができました。しかし、これは正しくないと思います。他の問題が発生すると思います。この問題に対する本当の解決策があるかどうか疑問に思っていました。それとも、これはhttps://stackoverflow.com/a/16998664からのパッチで対処する必要があり、それを適用すると何か問題が発生したのでしょうか?

私が読んだことから、nginxに切り替えると、このセットアップが簡単になる可能性があります。私はこれを検討しますが、nginxは他のことをより複雑にし、多くの時間を費やすため、可能であればApacheでこれを行いたいです.

4

5 に答える 5

17

この回答は、Fatih の回答に基づいています。彼のソリューションは、「キープアライブ、アップグレード」など、「アップグレード」以外の接続要求ヘッダーを送信するブラウザーでは失敗します。これは、Firefox 42 の場合に当てはまりました。

Firefox の問題にも取り組むには、Apache の RewriteCond を次のように変更します。

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

( ^Upgrade$Upgrade $ になります)

これを Fatih の回答にコメントしたかったのですが、必要な評判がありません。

于 2015-12-19T13:03:52.750 に答える
10

After reading several answers, posting on the Meteor forum, and a lot of trials here is the whole enchilada that worked for me. The other answers were somewhat incomplete, or at least didn't work for me.

I had to do:

sudo a2enmod proxy_wstunnel 

Also had to add a ProxyPass and ProxyPassReverse and changed ^Upgrade$ to Upgrade$ from another SO answer.

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

then restart Apache.

I checked on the console and there is no error now and no xhr requests. So I assume it's working correctly

于 2016-04-28T23:18:09.007 に答える
1

Derwiwieの修正によるFatih-Arslanの回答は魅力的でした。私のサービスは https でのみ動作するため、使用しなければならなかったことの 1 つは、 wsの代わりにwssを配置することでした。

RewriteEngine on  
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]  
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]  
RewriteRule .* wss://localhost:3000%{REQUEST_URI} [P]
于 2017-09-11T12:55:27.730 に答える