Handy Stadiumの構成
Handy Stadiumの構成を説明しましょう。Handy Stadiumでは「app.js」「roomData.js」「gameData.js」「gameServer.js」など、処理ごとにファイルを分けています。
- app.js
- WebSocketの管理、部屋の入出の管理
- roomData.js
- 部屋のデータ
- gameData.js
- ゲームのデータ
- gameServer.js
- ゲームの管理
クライアントの初期化、スタジアム(ルーム)の処理
クライアントの接続や、ルームへの入出の管理はapp.jsとroomData.jsで処理しています。
WebSocketのメッセージは文字列しか扱えないので、メッセージをプッシュするときはJSON.stringify()を使用してオブジェクトを文字列に変換します。受け取りの処理ではJSON.parse()を使用して文字列からオブジェクトへ変換します。
JSONのデータは以下のような形式になります。
{"type":"enterRoom","userId":"716037290","roomId":0,"roomStatus":1}
受け取ったメッセージはtypeプロパティの値を見て、どの情報についてのメッセージなのかを判別します。たとえば上記のメッセージの場合、「userIdが"716037290"のユーザーがroomIDが0の部屋に入った」という情報になります。
サーバーと同様、クライアントからもオブジェクトを文字列にしてメッセージをプッシュしますが、クライアントから受け取ったメッセージがJSON形式でない場合はパースに失敗するので、サーバー処理には例外処理を入れておきます。
var ws = require( 'websocket-server');
var server = ws.createServer();
//クライアントが接続したとき
server.addListener('connection',function(conn){
console.log('connect:'+conn.id);
//接続したクライアントにアプリの現在の状態を送信する。
conn.send(JSON.stringify({
type:'init',
rooms:roomData.rooms.map(function(x){return x.users.length;}),
userId:conn.id
}));
var openState = roomData.open(conn.id);
if(openState.type == 'error'){ console.log(openState); return; }
//全てのクライアントにユーザーが入ったことを知らせる
server.broadcast(JSON.stringify(
{type:'open',userId:conn.id}
));
//クライアントからメッセージが送信されたとき
conn.addListener('message',function(message){
try{
var data = JSON.parse(message);
}catch(e){
//JSONのパースに失敗した場合、JSONを投げたクライアントにエラーを返す。
conn.send(JSON.stringify({type:'error',message:'JSON.parse Error.',value:message}));
return;
}
var type = data.type;
if(type == 'enterRoom'){
//ユーザーが部屋に入った
}else if(type == 'exitRoom'){
//ユーザーが部屋から出た
}else if(type == 'game.setInningCount'){
//ユーザーが試合回数を選択した
}//以下省略
});
//クライアントが切断されたとき
conn.addListener('close',function(){
console.log('conn.close');
var roomState = roomData.exitRoom(conn.id);
//全てのクライアントにユーザーが切断したことを通知する。
conn.broadcast(JSON.stringify(
roomState
));
});
});