目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
■ 概要
- Node.js+socket.io+expressアプリはとっても簡単
- herokuにデプロイしたら予想外のところで詰まった
- 格闘ジャンケンゲームJANG Battle!みんな遊んでね!
■ リアルタイム通信するアプリを作ったことありますよね
こんにちは,Rails厨のわたなべ(hackugyo)です.
ところでみなさんはNode.jsって知っていますか.Node.jsのヴァージョンを管理するソフトにナベっていうのがあるんですが,私はワタナベなのでライバル視しています.
node.js+Socket.IOのNon-blockingI/O環境を見ると,一刻も早くリアルタイムに通信するアプリを作りたくなりますよね.私もそうです.ざっと見たところ,リアルタイム通信ときいて一番にみなさんが思いつくのはチャットアプリのようで,node.jsの前開発リーダRyan Dahlさんもgithubでサンプルを公開されています(https://github.com/ry/node_chat).
私も学習のためにチャットアプリを作ろうと思ったのですが,リアルタイム通信といえばゲームだよなと思い直し,途中から格闘ゲームに切り替えて作りました.といっても中身はほとんどチャットで,パンチ・ガード・ジャンプキックの3つのうちどれかをコマンド選択して,相手のコマンドとの相性で勝敗を決めるという,簡単なものです.
こちらがアプリです
対戦格闘じゃんけんゲーム
- ぐー・ちょき・ぱーから手を選びます
- 他のプレイヤの選んでいる手に勝っていれば,1点ゲット
- 連打によってどんどん点を稼げます
- 他のプレイヤがリアルタイムに手を変えるので,同じ手を連打していても勝てないかもしれません
- 20点とったら勝ちです
このアプリの作成にあたっては,ゲーマの友人の今井晋さん(facebookページ)より企画・アイデアをいただきました.貴重なアイデアを無償で公開していただき感謝します.
勝敗判定など,今後もアップグレードを続けていきます!
(ソースもこちらで公開します.https://github.com/hackugyo/ChatJangBattle)
■ ヘロクにデプロイする
さて,せっかく作ったのですから,localhostで動かすだけでなく,公開してみんなに遊んでもらいたいものです.チャットアプリもそうですが,リアルタイム通信の面白みを知るにはやはり多くのクライアントをさばく様子を見たいわけです.ましてや今回は対戦型格闘ゲームを作ってしまったので,ひとりで複数タブからパンチ……ガード……していてもむなしいだけです.
最近は恐ろしいことに,Paasなホスティング環境が無料でたくさんそろっています.DotCloud, Cloud Foundry, OpenShift, Node Ninja, Nodejitsu, etc.(node.js対応のホスティング環境の一覧はこちらにまとまっています).いまやWebアプリを試すのにも,localだけで満足する理由はほとんどなくなりました(セキュリティまわりの問題はありますが).さあ,どこにホスティングさせてもらいましょうか?
さあ,私はRails厨なので、ここでもちろんHerokuを選びます.HerokuはRubyの作者まつもとゆきひろ氏をチーフアーキテクトに迎えるなど,Rubyに対しなみなみならぬ優しさをもったプラットフォームです.言語としてはほかにもScala, Java, Pythonなどにも対応しており,もちろんnode.jsもOKです.
herokuデプロイ時の注意
masterブランチをpushすること
gitを利用し,ふだんのヴァージョン管理とほとんど変わらない気軽さでデプロイできるのが,Herokuの大きな魅力ですが,ここにはちょっとした心理的落とし穴があります.
私は最近,gitのブランチモデルについて勉強し,release / develop / featureなどのブランチをごりごり切り替えて使っているのですが,その影響で,herokuに大してもうっかり
$ git push heroku release
とreleaseブランチをpushしてしまったのです.これではさしものherokuも理解してくれません.ここは,正しくは
$ git push heroku relase:master
とすべきでした.あるいは,おとなしくmasterブランチをrelease目的に使ってもいいでしょうね.
ポート番号には注意
ローカル環境でWebアプリを試して,それをherokuにデプロイする場合,気をつけたいのはポート番号の設定です.ほかにも,Procfileを書くなどの追加点はありますが,既存のソースに手を入れるのはつい忘れがちです.
さて,ローカル環境で試したWebアプリには,主に2カ所,ポート番号を書いているところがあります.
- サーバサイドのjs
- クライアントサイドのjs
あたりまえですね.
サーバサイドは簡単です.app.jsのここを
var port = 5000;
app.listen(port, function(){
console.log("Express server listening on port %d in %s mode",
app.address().port, app.settings.env);
});
こう変えるわけです.
var port = process.env.PORT || 5000;
app.listen(port, function(){
console.log("Express server listening on port %d in %s mode",
app.address().port, app.settings.env);
});
これで,herokuデプロイ時にはprocess.env.PORTの値が使われるようになります.(デフォルトポートが5000なのは,foremanというマネージャに合わせたためです)
問題はクライアントです.jadeからclient.jsを切り出したのはいいのですが,その中でこういう記述をしていました.
var socket = io.connect('http://localhost:5000/chat');
// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
...
});
ソケット接続を要求するためのコードですが,ポート5000がまるのまま出てきていますね.io.connectを使った書きかたは,node.jsのv0.7以降で登場したものだそうで,ネットを見てもあまり情報がありません.
ここは素直にこう変えます.
var socket = io.connect('/chat');
// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
...
});
これで,ポートやホスティング先URLに関係なく,正しい接続要求をすることができます.
みなさんもnode.jsでherokuに楽しいアプリを作ってください!
■ ご参考
- herokuへのnode.jsアプリのデプロイについては,本家ブログに記事があります. https://devcenter.heroku.com/articles/nodejs
- node.jsじたいの解説は, Web+DBPRESS vol.58(技術評論社, 2012)の特集”Node.js実践入門”がたいへん参考になります.著者は名村卓(@snamura)さんです.
- チャットアプリのUIについては,いくつもライブラリが公開されています.最近だとBaloons.IOなどかっこいい. https://github.com/gravityonmars/Balloons.IO
- テンプレートエンジンにはexpressのデフォルトのJadeを使いました.こちらのコンヴァータは便利:http://html2jade.aaron-powell.com/
- 開発環境はEmacsでしたが,Nideもちょっと触りました.面白いですね.http://coreh.github.com/nide/