nginxでsocket.ioのリバースプロキシ設定
今更だけどもnginxをリバプロに使ってsocket.ioを動かす方法を覚書。
nginx_tcp_proxy_module
If you’re using nginx, you won’t be able to proxy web socket connections using the standard nginx proxy_pass directives.
Fortunately, Weibin Yao has developed a tcp proxy module for nginx that allows you to reverse proxy general tcp connections, especially well suited for websockets.
http://www.letseehere.com/reverse-proxy-web-sockets
上の記事やgithubのsocket.ioのwikiにも書いてありますが、どうもnginxは最新安定版の1.0ではhttp 1.1のupgradeをサポートしておらず、またnginx1.1ではhttp1.1のupgradeはサポートしているものの、websocketをサポートしていないために、socket.ioのプロキシが上手くいかないようです。
(確かsocket.ioは最初xhrで接続して、クライアントがwebsocket使えたらwebsocketにupgradeするという流れだった気がするけどソース忘れた)
まぁそんなわけで、現時点では素のnginxでsocket.ioのリバースプロキシは行えないということです。そこで上の引用にもあるように、「nginx_tcp_proxy_module」というモジュールを組み込んでこの問題を解決します。
前回記事にも書いたように、nginxの追加モジュールはソールコンパイル時にオプションとして指定しなければなりません。
nginxのソースと共にモジュールをgithub(https://github.com/yaoweibin/nginx_tcp_proxy_module)から持ってきて、パッチをあててコンパイルします。
$ wget http://nginx.org/download/nginx-1.0.11.tar.gz $ tar zxvf nginx-1.0.11.tar.gz $ cd nginx-1.0.11 $ git clone https://github.com/yaoweibin/nginx_tcp_proxy_module.git $ patch -p1< nginx_tcp_proxy_module/tcp.patch $ ./configure --add-module=./nginx_tcp_proxy_module $ make $ make install
その他のコンパイルオプションなどについては前回記事を参照してください。
モジュールの設定方法
このモジュールをインストールすると、設定ファイル内で新たにtcpブロックが使えるようになります。このブロック内にsocket.io向けの設定を書いていくことになります。
tcp { upstream websockets { ## node processes server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; server 127.0.0.1:8004; check interval=3000 rise=2 fall=5 timeout=1000; } server { listen 127.0.0.1:80; server_name _; tcp_nodelay on; proxy_pass websockets; } } http { ## status check page for websockets server { listen 9000; location /websocket_status { check_status; } } }
上記の設定はhttp://www.letseehere.com/reverse-proxy-web-socketsのをそのままもってきました。
基本的には設定はhttpブロックを使うときとそんなに変わりません。tcpブロック内のserverブロックでホスト名やlistenポートを指定し、proxy_passでリバースプロキシの設定を行います。あとはupstreamブロック内にアクセスを振り分けるサーバを指定すれば終わりです。checkディレクティブはヘルスチェックの設定を行います。
ちなみに上記の設定でhttpブロック内に check_status というディレクティブがありますが、これをhttpブロック内で指定すると、upstreamに書かれているサーバへのヘルスチェックの簡易確認ページを見ることができます。以下のような感じです。
他のディレクティブなどの説明に従いてはhttps://github.com/yaoweibin/nginx_tcp_proxy_module
では適当につないでみます。
サーバ側コード
var http = require('http'), io = require('socket.io'); var server = http.createServer(function(req, res){ res.writeHead(200, {'Content-Type': 'text/html'}); res.end('Hello world'); }); server.listen(8008); // socket.io var socket = io.listen(server); socket.on('connection', function(client){ console.log('client has connected'); });
ポートが8008なのは僕の家の環境のせいなので適当に読み替えてください。これを対象のサーバで実行すると
上手く行ってるみたいですね。これで完了です。