以前の記事で、Node.jsという開発言語を用いて、Unityのandroid無償版からインターネットアクセスする、という話題を扱った。
【制作実習】Unityのandroid無償版からNode.jsで動くRESTサーバーへの疎通テスト
来週から、より掘り下げて、コールアンドマジックのゲームサーバーとして利用できるか検証に入る予定だ。
今日は、その準備段階として、Node.jsを勉強しながら、簡単なRESTサービスを作ってみた。
サービスの仕様は簡単なもので以下の機能を備える。
・ユーザー登録:
クライアントからユーザー名を送ると、一意のアカウントIDを返してくれる。
このアカウントIDをゲームクライアント側で保持して、以降はこのIDでアクセスする。
サーバー側は、IDの生成と、ユーザー名、IPアドレス、最終アクセス日時をデータベースに登録する。
・ヘルスチェック:
アカウントIDを送ると、データベースに登録されたアカウントの最終アクセス日時を更新する。
たとえば、ダンジョン内やネットワーク対戦をするために、クライアントは定期的(30秒以内)にヘルスチェックをサーバーに送る。
・接続ユーザー一覧取得:
アカウントIDを送ると、直近30秒以内にサーバーにアクセスがあった全ユーザー一覧を返す。
ゲームから離脱したユーザーは30秒後にリストから姿を消していく。
機能自体は簡単なものなので、ソースも解説も不要だと思う。
Node.jsにもデータベースのMySQLに接続するためのモジュールが公開されているため、データベース側の処理も簡単に実装できた。
ひとつ心配な点は、Node.jsのアーキテクチャが、シングルスレッドの非同期のシステムとなっているため、実装がやや特殊な形になるというところ。
言い換えると、規模が大きくなるにつれて、加速度的にコード量やデバッグ量が増えていくのではないかという心配もある。
たとえば、データベースやファイルIOを伴うWEBサービスを例に従来型のプログラミングとの違いを簡単に述べてみる。
【Servletなどの従来のマルチスレッドプログラミング】
これは、リクエストごとにスレッドが割り当てられる。
データベース処理やIOなど時間のかかる処理でも、ほとんどの場合、結果が返ってくるのを待って、その結果に対して後続の処理を記述していく。
そのため、処理の流れが追いやすい。つまり実装しやすく、メソッドやプロセス間が疎結合となるような設計が容易である。
【Node.jsのシングルスレッド、非同期プログラミング】
全体のプロセスが、時間がかかる処理ごとに分断されて、イベントキューにいったん保留される。
イベントキューに入れられた処理が仕事を終えた時点で、コールバックという形で後続の処理が数珠繋ぎに呼び出されていく。
そのため、処理の流れが追いにくい。つまり実装が煩雑になりやすい。
たとえば、エラー処理などはうまく設計しないと、各イベント処理ごとに似たような処理を書いてしまいがちになる。
ただ、こういった欠点というか癖のある性質を補って余りあるほど、Node.jsは手軽で便利であることに変わりはない。
とにかくトライアンドエラーがやりやすいので、ちょっとしたテストサーバーを作るには、いまのところベストプラクティスのような気がする。
仕事でもない限り、JSPやEJBなんかの重厚なWEB系フレームワークには戻れないかもしれない。