今更ながら、nginx+Mojolicious+WebSocketでチャットアプリに挑戦
最近は、Unityばかり触れていて、Perlしてなかったので LTネタも尽きてしまう。というわけで こちらのエントリーを参照して、Mojoliciousでチャットアプリを作ったのは いいのだけど、本番環境では動かなかった。
http://kazuph.hateblo.jp/entry/20120310/1331396492
ソースはこちら。 https://github.com/dokechin/chat_web
原因を調べていくと・・・
$ /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.2.1
nginxのバージョンが低いからかな。。
http://stackoverflow.com/questions/12102110/nginx-to-reverse-proxy-websockets-and-enable-ssl-wss
nginxのインストール方法を忘れてしまったので、 自分のページを参照 http://stingyrunner.blog.fc2.com/blog-entry-46.html
さて、インストールしなくては。今日はここまで・・・
nginx1.6.0をインストールしてみたけれど、404が返ってくる。ううぅ。
143.90.238.110 - - [28/May/2014:08:03:30 +0900] "GET /echo HTTP/1.1" 404 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0"
クライアントが渡しているヘッダ
nginxの設定
upstream chat { server 127.0.0.1:8012; } server { listen 80; server_name chat.dokechin.com; #server_name www24203ue.sakura.ne.jp; #index index.html; root /home/tatsumi/chat/public; access_log /var/log/chat.access.log main; location / { proxy_set_header X-Forwarded-Proto "http"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://chat; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
Mojoliciousまでは来ているただし、ログが違う
開発機
[Thu May 29 05:34:59 2014] [debug] GET "/echo". [Thu May 29 05:34:59 2014] [debug] Routing to controller "Chat::Web::Chat" and action "echo". [Thu May 29 05:34:59 2014] [debug] Client connected: Mojo::Transaction::WebSocket=HASH(0x80e808c0) [Thu May 29 05:34:59 2014] [debug] 101 Switching Protocols (0.018193s, 54.966/s).
本番機
[Thu May 29 05:31:40 2014] [debug] GET "/echo". [Thu May 29 05:31:40 2014] [debug] Template "not_found.development.html.ep" not found. [Thu May 29 05:31:40 2014] [debug] Template "not_found.html.ep" not found. [Thu May 29 05:31:40 2014] [debug] Rendering inline template. [Thu May 29 05:31:40 2014] [debug] Rendering inline template. [Thu May 29 05:31:40 2014] [debug] 404 Not Found (0.027890s, 35.855/s).
MojoliciousでHTTPヘッダー情報をログ出力したい
hookを利用して、ヘッダー情報をログ出力するように変更。
package Chat::Web; use Mojo::Base 'Mojolicious'; # This method will run once at server start sub startup { my $self = shift; # Router my $r = $self->routes; $self->hook( before_dispatch=> sub { my $c = shift; $c->app->log->info($c->req->headers->to_string); }); # Normal route to controller $r->websocket ('/echo')->to('chat#echo'); $r->get ('/')->to('chat#index'); } 1;
ヘッダーの比較
開発機
Connection: keep-alive, Upgrade Cache-Control: no-cache Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Origin: http://localhost:3000 Accept-Encoding: gzip, deflate Sec-WebSocket-Version: 13 Host: localhost:3000 Pragma: no-cache Sec-WebSocket-Key: rr6RE14/sECc7i47y7mjew== Upgrade: websocket
本番機
Connection: upgrade^M Cache-Control: no-cache^M Cookie: __utma=32193579.732112302.1369506740.1386651262.1393706303.4; __utmz=32193579.1393706303.4.4.utmcsr=yahoo|utmccn=(organic)|utmcmd=organic|utmctr=page_navigator%20mojolicous; _ga=GA1.2.732112302.1369506740^M Origin: http://chat.dokechin.com^M DNT: 1^M Sec-WebSocket-Version: 13^M Host: chat.dokechin.com^M Sec-WebSocket-Key: 7F70rz9ewewN9kEshfDv5Q==^M X-FORWARDED-PROTO: http^M X-FORWARDED-FOR: 143.90.238.110^M Upgrade: Websocket
なんか微妙に違う気がする。これらを合わせていこう こんな風に合わせてみたが404のまま
Connection: keep-alive, Upgrade^M Cache-Control: no-cache^M Cookie: __utma=32193579.732112302.1369506740.1386651262.1393706303.4; __utmz=32193579.1393706303.4.4.utmcsr=yahoo|utmccn=(organic)|utmcmd=organic|utmctr=page_navigator%20mojolicous; _ga=GA1.2.732112302.1369506740^M Origin: http://chat.dokechin.com^M DNT: 1^M Sec-WebSocket-Version: 13^M Host: chat.dokechin.com^M Sec-WebSocket-Key: qHl4SaSgqsiMW/x+KaVKbA==^M X-FORWARDED-PROTO: http^M X-FORWARDED-FOR: 143.90.238.110^M Upgrade: websocket
本番環境をstartlet→morboに変えたら・・
あっさりと動いた。ということはnginxの設定はあっているのかな。
morbo+Mojoliious(websoket)は動くけれど、starman+Mojolicious(websoket) では動かないということか。
Connection: keep-alive, Upgrade^M Cache-Control: no-cache^M Cookie: __utma=32193579.732112302.1369506740.1386651262.1393706303.4; __utmz=32193579.1393706303.4.4.utmcsr=yahoo|utmccn=(organic)|utmcmd=organic|utmctr=page_navigator%20mojolicous; _ga=GA1.2.732112302.1369506740^M Origin: http://chat.dokechin.com^M DNT: 1^M Sec-WebSocket-Version: 13^M Host: chat.dokechin.com^M Sec-WebSocket-Key: qSDYkQmqZ9DZEYnS8SoKJA==^M X-Forwarded-Proto: http^M X-Forwarded-For: 210.160.37.30^M Upgrade: websocket
開発環境でもplackupで起動すると動かなかった
plackup --port 3000 chat.psgi
うーん。いまいち理解していないけれど。
psgiサーバ(starmanやstartlet)でWebSocketを使う時は、MojoliciousでやらずにPlack::App::WebSocketを使うということなのかな。 うーん。それは作りにくいなぁ。。
本番環境hypnotoadへ
結局、本番環境starmanを諦め、hypnotoadへ。
ランチャー
#!/bin/bash HOME=~ . ~/.bash_profile exec hypnotoad -f /home/tatsumi/chat/script/chat_web
Configファイルの用意(chat.conf)
{ hypnotoad => { listen => ['http://*:8012'], workers => 10 } };
Configの読み込み部分の用意
package Chat::Web; use Mojo::Base 'Mojolicious'; # This method will run once at server start sub startup { my $self = shift; # Router my $r = $self->routes; my $config = $self->plugin( 'Config', { file => 'chat.conf' } ); # Normal route to controller $r->websocket ('/echo')->to('chat#echo'); $r->get ('/')->to('chat#index'); } 1;