オンラインゲームとか作ってみたい#1 node.js

なんかオンラインゲームつくりたいなと昔から思ってて(昔MMO廃人になってたときがあったり)、nodejsとunityできれば作れるんちゃうんと軽い気持ちでまずnodejsからやってみた。(jsて新しい会社来てからやるようになったけどなんでもできるんやなぁ)
がしかし簡単なチャットゲーム作るだけでも同期周りが大変。mmoやってたころはなんでこんなバグ出してメンテばっかりしてるんだ糞運営みたいに思ってたけど、確かにネットワークプログラミングってクライアント側もサーバ側もどっちも作業重いから難しい気がする。コルムオンラインの運営の方々ごめんなさい。

参考書はこれがいいっぽいから買った。
はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-http://www.amazon.co.jp/dp/4797370904

node.jsできること
・v8エンジンがjsをネイティブ言語に変換してくれるので、jsでネイティブでできることができる。
・ファイル操作やhttpサーバーを立てたりできる。
・ファイル監視(更新されたかどうか)とかもできるので、Grunt.jsってjsなのになんで勝手にファイルまとめたりできんのって思ってたけどその機能を使ってるぽい
・socket.ioというモジュールを使う事で双方向な通信を簡単にできる。

デメリット
・一つ一つ処理をしていくのでCPUを使う様な処理が入ると全体のパフォーマンスが下がる
・コールバック地獄
・バージョンアップしまくっててドキュメントがすぐ過去になる、安定してないとこもある
・なんか文法エラーがあるとサーバー全体がとまる(小さなミスがクリティカルな問題に)

以下雑なメモ

▼概念
・スレッドモデル
リクエスト毎にスレッドを立ち上げる
・イベントループ←こっち
メインのスレッドは一つ。シングルスレッドモデル
※処理がおわるのはバラバラ
※ループをやめないようにノンブロックな書き方にする

// non blockingな書き方例
setTimeout(function(){
console.log("aaa");
},1000);
console.log("aaa22");

// non blockingじゃない書き方例
// 次の行の実行をwhile文でブロックしちゃってるから全体の処理がとまる
var start = new Date().getTime();
while( new Date().getTime() < start + 1000 );
console.log("aaa");

▼使い方
$ node ファイル名
ex. ) $ node hello.js

モジュール(クラス的なイメージ?
//モジュール読み込み
require(module名)

requireは実行結果をキャッシュしており、複数回ロードした場合、最初の一回のみ実行される
require(./ディレクトリ名)でディレクトリ対象でできるpackage.jsonあったら読む、なかったらindex.js index.node
module名がコアモジュールになければ、node_modulesフォルダを見に行く。.js省略できる。そのばあい.js .json .nodeの順で読んでいく

・nodejsのコアモジュール
http https fs events dgramなど

・exportsオブジェクトとは
モジュール内は暗黙の名前空間があり、直接参照できない。
exportsオブジェクトだけモジュール外から参照できる。(publicなメソッドや関数を作れる)

ex.)

/* hello.js */
var myName = "taro";
exports.myName = myName;

function greeting( _smothing ){
console.log( _somthing + " hello !!" );
}
exports.greeting = greeting;
/* main.js */
var hello =[javascript] require("./hello.js");
hello.greeting( hello.myName );
// > taro hello !!

npm操作
//インストール
$ npm install mysql
//アンインストール
$ npm uninstall mysql
-gをつけるとグローバルパッケージでin unin できる

httpサーバ
・requestを受ける
get postで送れるものは受け取れる(画像とかも)
・responseする
writeHeadでhttpステータスコード(200:成功 500:Internal server error 404:not foundなど)とhttpヘッダー(省略可)を返す
writeHeadメソッドはwriteやendメソッドを呼び出す前に必ず1回呼び出す必要がある
文字列やバイナリデータを送れる

Socket.IO
flashから使う時はExternalInterface経由でやるっぽい。
参考 ≫ http://blog.glasses-factory.net/2011/10/17/GFS-I-OAS3—Socket-IO-AS3-WebSocket

参考
デメリットまとめ ≫ http://qiita.com/hshimo/items/156249ec8e6dbf75205a
Node.js読み物 ≫ http://readwrite.jp/archives/2539