1.首先進入房間有四種途徑
a.進入大廳界面的時候查看是個有oldRoomId,如果有直接進入對應房間
b.大廳界面update方法裏看是否有cc.vv.userMgr.roomData,如果有直接進入對應房間
c.根據房間號輸入對應房間的時候,如果正確,則進入房間
d.用戶斷線重連的時候,如果房間號存在,則直接進入房間
2.接下來就是進入房間實際操作
enterRoom:function(roomId,callback){
var self = this;
var onEnter = function(ret){
if(ret.errcode !== 0){
if(ret.errcode == -1){
setTimeout(function(){
self.enterRoom(roomId,callback);
},5000);
}
else{
cc.vv.wc.hide();
if(callback != null){
callback(ret);
}
}
}
else{
cc.vv.wc.hide();
if(callback != null){
callback(ret);
}
cc.vv.gameNetMgr.connectGameServer(ret);
}
};
var data = {
account:cc.vv.userMgr.account,
sign:cc.vv.userMgr.sign,
roomid:roomId
};
cc.vv.wc.show("正在進入房間 " + roomId);
cc.vv.http.sendRequest("/enter_private_room",data,onEnter);
},
跳轉到client_server的對應方法處
app.get('/enter_private_room',function(req,res){
var data = req.query;
var roomId = data.roomid;
if(roomId == null){
http.send(res,-1,"parameters don't match api requirements.");
return;
}
if(!check_account(req,res)){
return;
}
var account = data.account;
db.get_user_data(account,function(data){
if(data == null){
http.send(res,-1,"system error");
return;
}
var userId = data.userid;
var name = data.name;
//驗證玩家狀態
//todo
//進入房間
room_service.enterRoom(userId,name,roomId,function(errcode,enterInfo){
if(enterInfo){
var ret = {
roomid:roomId,
ip:enterInfo.ip,
port:enterInfo.port,
token:enterInfo.token,
time:Date.now()
};
ret.sign = crypto.md5(roomId + ret.token + ret.time + config.ROOM_PRI_KEY);
http.send(res,0,"ok",ret);
}
else{
http.send(res,errcode,"enter room failed.");
}
});
});
});
第一步驗證賬號,接着獲取用戶uid和暱稱,執行room_server的enterRoom方法
exports.enterRoom = function(userId,name,roomId,fnCallback){
var reqdata = {
userid:userId,
name:name,
roomid:roomId
};
reqdata.sign = crypto.md5(userId + name + roomId + config.ROOM_PRI_KEY);
var checkRoomIsRuning = function(serverinfo,roomId,callback){
var sign = crypto.md5(roomId + config.ROOM_PRI_KEY);
http.get(serverinfo.ip,serverinfo.httpPort,"/is_room_runing",{roomid:roomId,sign:sign},function(ret,data){
if(ret){
if(data.errcode == 0 && data.runing == true){
callback(true);
}
else{
callback(false);
}
}
else{
callback(false);
}
});
}
var enterRoomReq = function(serverinfo){
http.get(serverinfo.ip,serverinfo.httpPort,"/enter_room",reqdata,function(ret,data){
console.log(data);
if(ret){
if(data.errcode == 0){
db.set_room_id_of_user(userId,roomId,function(ret){
fnCallback(0,{
ip:serverinfo.clientip,
port:serverinfo.clientport,
token:data.token
});
});
}
else{
console.log(data.errmsg);
fnCallback(data.errcode,null);
}
}
else{
fnCallback(-1,null);
}
});
};
var chooseServerAndEnter = function(serverinfo){
serverinfo = chooseServer();
if(serverinfo != null){
enterRoomReq(serverinfo);
}
else{
fnCallback(-1,null);
}
}
db.get_room_addr(roomId,function(ret,ip,port){
if(ret){
var id = ip + ":" + port;
var serverinfo = serverMap[id];
if(serverinfo != null){
checkRoomIsRuning(serverinfo,roomId,function(isRuning){
if(isRuning){
enterRoomReq(serverinfo);
}
else{
chooseServerAndEnter(serverinfo);
}
});
}
else{
chooseServerAndEnter(serverinfo);
}
}
else{
fnCallback(-2,null);
}
});
};
這兒首先根據房間號查詢了房間信息,包括對應的遊戲服務器ip和端口,如果服務器存在,查看房間是否正在運行,如果在運行,執行進入房間的請求,否則,選擇一個合適的服務器,然後執行進入房間請求
時間進入房間的操作在遊戲服務器的http_server裏面
app.get('/enter_room',function(req,res){
var userId = parseInt(req.query.userid);
var name = req.query.name;
var roomId = req.query.roomid;
var sign = req.query.sign;
if(userId == null || roomId == null || sign == null){
http.send(res,1,"invalid parameters");
return;
}
var md5 = crypto.md5(userId + name + roomId + config.ROOM_PRI_KEY);
console.log(req.query);
console.log(md5);
if(md5 != sign){
http.send(res,2,"sign check failed.");
return;
}
//安排玩家坐下
roomMgr.enterRoom(roomId,userId,name,function(ret){
if(ret != 0){
if(ret == 1){
http.send(res,4,"room is full.");
}
else if(ret == 2){
http.send(res,3,"can't find room.");
}
return;
}
var token = tokenMgr.createToken(userId,5000);
http.send(res,0,"ok",{token:token});
});
});
老一套的參數檢查,最後調用roomMgr.enterRoom操作數據庫
exports.enterRoom = function(roomId,userId,userName,callback){
var fnTakeSeat = function(room){
if(exports.getUserRoom(userId) == roomId){
//已存在
return 0;
}
for(var i = 0; i < 4; ++i){
var seat = room.seats[i];
if(seat.userId <= 0){
seat.userId = userId;
seat.name = userName;
userLocation[userId] = {
roomId:roomId,
seatIndex:i
};
//console.log(userLocation[userId]);
db.update_seat_info(roomId,i,seat.userId,"",seat.name);
//正常
return 0;
}
}
//房間已滿
return 1;
}
var room = rooms[roomId];
if(room){
var ret = fnTakeSeat(room);
callback(ret);
}
else{
db.get_room_data(roomId,function(dbdata){
if(dbdata == null){
//找不到房間
callback(2);
}
else{
//construct room.
room = constructRoomFromDb(dbdata);
//
var ret = fnTakeSeat(room);
callback(ret);
}
});
}
};
首先查看房間是否存在,如果存在,則takeSeat,否則,根據房間號查找數據庫 ,然後根據數據庫信息創建房間,增加房間數等
下面看看takeSeat的邏輯
var fnTakeSeat = function(room){
if(exports.getUserRoom(userId) == roomId){
//已存在
return 0;
}
for(var i = 0; i < 4; ++i){
var seat = room.seats[i];
if(seat.userId <= 0){
seat.userId = userId;
seat.name = userName;
userLocation[userId] = {
roomId:roomId,
seatIndex:i
};
//console.log(userLocation[userId]);
db.update_seat_info(roomId,i,seat.userId,"",seat.name);
//正常
return 0;
}
}
//房間已滿
return 1;
}
如果房間存在,則返回
,然後遍歷四個座位,如果某一座位爲空,則更新數據庫信息,然後返回,否則,就是房間滿了