web-dev-qa-db-ja.com

Apache2を設定してWebSocketをプロキシしますか?

WebSocketプロトコルは、HTTPプロトコルの拡張です。ただし、Apache2のプロキシモジュールはそれを認識していないようで、重要なヘッダーを破棄し、呼び出しを標準のHTTP呼び出しに変換します。

Apache2に(1)WebSocketを理解させる方法、または(2)取得したものをそのまま盲目的に渡す方法はありますか?

41
Blixt

Mod_proxy(ProxyPass/ProxyPassReverse)がWebSocketトラフィックを通過できるようにするmod_proxy_wstunnelと呼ばれるモジュールがApacheトランクに追加されました。誰かが back-porting mod_proxy_wstunnel to Apache 2.4/2.2 についてブログ記事を書き、そうするためのパッチを提供しました。

具体的な buntuでmod_proxy_wstunnelを設定する手順 (Ubuntu Server 11.10とApache 2.2.20でテスト済み)を見つけて、ブログに投稿しました。以下にコピーしました:

# Check Apache version (should be 2.2.20 as of writing, if not adjust the next step)
dpkg -s Apache2

# Checkout Apache source
svn checkout http://svn.Apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20

# Get patch and apply it
wget http://cafarelli.fr/gentoo/Apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../Apache-2.2.24-wstunnel.patch

# Build Apache 
svn co http://svn.Apache.org/repos/asf/apr/apr/branches/1.4.x srclib/apr
svn co http://svn.Apache.org/repos/asf/apr/apr-util/branches/1.3.x srclib/apr-util
./buildconf
./configure --enable-proxy=shared --enable-proxy_wstunnel=shared
make

# Copy the module and recompiled mod_proxy (for new symbols) to the ubuntu Apache installation and update the permissions to match the other modules
Sudo cp modules/proxy/.libs/mod_proxy{_wstunnel,}.so /usr/lib/Apache2/modules/
Sudo chmod 644 /usr/lib/Apache2/modules/mod_proxy{_wstunnel,}.so
echo -e "# Depends: proxy\nLoadModule proxy_wstunnel_module /usr/lib/Apache2/modules/mod_proxy_wstunnel.so" | Sudo tee -a /etc/Apache2/mods-available/proxy_wstunnel.load

# Enable the module (also make any configuration changes you need)
Sudo a2enmod proxy_wstunnel
Sudo service Apache2 restart
23
Andrew Moss

指定するものはありません Apache httpdはいつでもそれらをサポートします。

Apache経由でwebsocketを実行する必要がある場合は、 mod_pywebsocket を試してください。私はそれを試しました、そしてそれはうまくいきます。

ここに私が好むいくつかの選択肢があります:

11
h0tw1r3

切断プラグインといくつかの追加コードの組み合わせでこれが可能になりました:

http://blog.alex.org.uk/2012/02/16/using-Apache-websocket-to-proxy-tcp-connection/

6
pablojim

http://github.com/disconnect/Apache-websocket をご覧ください。

Apache-websocketモジュールは、Apache 2.xサーバーがWebSocketプロトコルを使用してリクエストを処理するために使用できるApache 2.xサーバーモジュールです。

4
Marat Denenberg

Socket_io 1.0で動作するようにVirtualHostを正しく構成する方法については、@ Andrew Moss 'の回答を追加してください! CentOSに関する部分は省略してかまいません。


CentOS 6でスタックしている場合は、次の方法で行います。

  1. mod_proxy_wstunnelモジュールのバックポートされたソースをダウンロード here (Gistを複製するか、ファイルを個別にダウンロードします)
  2. ビルドに必要なすべてのものをインストールします:yum install make gcc httpd-devel
  3. RPMビルド環境 をセットアップします(基本的には非特権ユーザーといくつかのディレクトリ)
  4. .c-ファイルを環境のSOURCESサブフォルダーにコピーし、.spec-ファイルをSPECSサブフォルダーにコピーします。
  5. rpmbuild -ba mod_proxy_wstunnel.specを実行します
  6. パッケージはSRPMSサブフォルダーにあります
  7. パッケージをインストールします:rpm -i /path/to/package.rpm
  8. 利益

これにより、モジュールが自動的にApacheに読み込まれるため、service httpd restartで再起動するだけです。


実際にSocket.ioサーバーとクライアントスクリプト(http://your.server/socket.io/socket.io.jsの下でデフォルトで使用可能)にサービスを提供するVirtualHostの設定は、Apache 2.2では mod_proxyモジュールのバグ

次の書き換えルールがあるとします。

RewriteRule    ^/ws(.*)$  ws://localhost:9000/ws  [P]

mod_rewriteはこれをファイルパスとして扱い、アクセスログに次のように表示します。

[26/Sep/2013:09:46:07 -0400] "GET /ws://localhost:9000/ws HTTP/1.1" 400 317

したがって、rewrite-rulews- protocolを使用することはできません。これは、内部的にHTTP GETリクエストになるためです。 。

ただし、回避策があります。

<VirtualHost *:80>
        ServerName your.server

        # Proxy socket.io Websocket
        RewriteEngine On

        # socket.io 1.0+ starts all connections with an HTTP polling request
        RewriteCond %{QUERY_STRING} transport=polling       [NC]
        RewriteRule /(.*)           http://localhost:8081/$1 [P]

        ProxyRequests Off

        # Explicitly send the request for the client-script to HTTP:
        ProxyPass /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
        ProxyPassReverse /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js

        # Anything else goes to the WebSocket protocol:
        ProxyPass /socket.io/ ws://localhost:8081/socket.io/
        ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/

        # Any additional stuff (the actual site) comes here
        ProxyPass / http://localhost:8081/
        ProxyPassReverse / http://localhost:8081/
</VirtualHost>

これにより、/socket.ioに送信されるすべてのものがws://プロトコルに確実に送信されます。ただし、ロングポーリングのリクエスト(WebSocketが使用できない場合のフォールバックメカニズム)とクライアントライブラリのリクエストは除きます。 。

1
Lukas Knuth