-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
v_jiangxinyu01
committed
May 16, 2020
1 parent
7b25dc2
commit f292d32
Showing
7 changed files
with
1,439 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** 主命令字定义 **/ | ||
var MainCmd = { | ||
CMD_SYS : 1, /** 系统类(主命令字)- 客户端使用 **/ | ||
CMD_GAME : 2, /** 游戏类(主命令字)- 客户端使用 **/ | ||
} | ||
|
||
/** 子命令字定义 **/ | ||
var SubCmd = { | ||
//系统子命令字,对应MainCmd.CMD_SYS | ||
LOGIN_FAIL_RESP : 100, | ||
HEART_ASK_REQ : 101, | ||
HEART_ASK_RESP : 102, | ||
BROADCAST_MSG_REQ : 103, | ||
BROADCAST_MSG_RESP : 104, | ||
|
||
//游戏逻辑子命令字,对应MainCmd.CMD_GAME | ||
SUB_GAME_START_REQ : 1, //游戏开始---> CGameStart | ||
SUB_GAME_START_RESP : 2, //游戏开始---> CGameStart | ||
SUB_USER_INFO_RESP : 3, //用户信息 ------> CUserInfo | ||
SUB_GAME_SEND_CARD_RESP : 4, //发牌 ------> CGameSendCard | ||
SUB_GAME_CALL_TIPS_RESP : 5, //叫地主提示(广播) --> CGameCall | ||
SUB_GAME_CALL_REQ : 6, //叫地主请求 --> CGameCallReq | ||
SUB_GAME_CALL_RESP : 7, //叫地主请求返回--CGameCallResp | ||
SUB_GAME_DOUBLE_TIPS_RESP : 8, //加倍提示(广播) --> CGameDouble | ||
SUB_GAME_DOUBLE_REQ : 9, //加倍请求--> CGameDoubleReq | ||
SUB_GAME_DOUBLE_RESP : 10, //加倍请求返回----> CGameDoubleResp | ||
SUB_GAME_CATCH_BASECARD_RESP : 11, //摸底牌 ---> CGameCatchBaseCard | ||
SUB_GAME_OUT_CARD : 12, //出牌提示 --> CGameOutCard | ||
SUB_GAME_OUT_CARD_REQ : 13, //出牌请求 --> CGameOutCardReq | ||
SUB_GAME_OUT_CARD_RESP : 14, //出牌返回 --> CGameOutCardResp | ||
|
||
CHAT_MSG_REQ : 213, //聊天消息请求,客户端使用 | ||
CHAT_MSG_RESP : 214, //聊天消息响应,服务端使用 | ||
} | ||
|
||
|
||
/** | ||
* 路由规则,key主要命令字=》array(子命令字对应策略类名) | ||
* 每条客户端对应的请求,路由到对应的逻辑处理类上处理 | ||
* | ||
*/ | ||
var Route = { | ||
1 : { | ||
100 : 'loginFail', //登陆失败 | ||
105 : 'loginSuccess', //登陆成功 | ||
102 : 'heartAsk', //心跳处理 | ||
104 : 'broadcast', //广播消息 | ||
106 : 'enterRoomFail', //进入房间失败 | ||
107 : 'enterRoomSucc', //进入房间成功 | ||
}, | ||
2 : { | ||
2 : 'gameStart', //获取卡牌 | ||
214 : 'chatMsg', | ||
3 : 'userInfo', //显示用户信息 | ||
5 : 'gameCallTips', //叫地主广播 | ||
7 : 'gameCall', //叫地主返回 | ||
11 : 'gameCatchCardTips', //摸底牌 | ||
12 : 'gameOutCard', //出牌广播 | ||
14 : 'gameOutCardResp', //出牌响应 | ||
}, | ||
} | ||
|
||
/** | ||
* 花色类型 | ||
*/ | ||
var CardType = { | ||
HEITAO : 0, //黑桃 | ||
HONGTAO : 1, //红桃 | ||
MEIHUA : 2, //梅花 | ||
FANGKUAI : 3, //方块 | ||
XIAOWANG : 4, //小王 | ||
DAWANG : 5, //大王 | ||
} | ||
/** | ||
* 牌显示出来的值 | ||
*/ | ||
var CardVal = { | ||
CARD_SAN : '3', //牌值3 | ||
CARD_SI : '4', //牌值4 | ||
CARD_WU : '5', //牌值5 | ||
CARD_LIU : '6', //牌值6 | ||
CARD_QI : '7', //牌值7 | ||
CARD_BA : '8', //牌值8 | ||
CARD_JIU : '9', //牌值9 | ||
CARD_SHI : '10', //牌值10 | ||
CARD_J : 'J', //牌值J | ||
CARD_Q : 'Q', //牌值Q | ||
CARD_K : 'K', //牌值K | ||
CARD_A : 'A', //牌值A | ||
CARD_ER : '2', //牌值2 | ||
CARD_XIAOWANG : 'w', //牌值小王 | ||
CARD_DAWANG : 'W', //牌值大王 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/** | ||
* 初始化类,websock服务器类 | ||
*/ | ||
|
||
var Init = { | ||
ws : null, | ||
url : "", | ||
timer : 0, | ||
reback_times : 100, //断线重连次数 | ||
dubug : true, | ||
|
||
//启动websocket | ||
webSock: function (url) { | ||
this.url = url; | ||
ws = new WebSocket(url); | ||
ws.binaryType = "arraybuffer"; //设置为2进制类型 webSocket.binaryType = "blob" ; | ||
var obj = this; | ||
//连接回调 | ||
ws.onopen = function(evt) { | ||
Req.heartBeat(obj); | ||
//清除定时器 | ||
clearInterval(obj.timer); | ||
//获取用户状态 | ||
obj.log('系统提示: 连接服务器成功'); | ||
}; | ||
|
||
//消息回调 | ||
ws.onmessage = function(evt) { | ||
if(!evt.data) return ; | ||
var total_data = new DataView(evt.data); | ||
var total_len = total_data.byteLength; | ||
if(total_data.byteLength < 4){ | ||
obj.log('系统提示: 数据格式有问题'); | ||
ws.close(); | ||
return ; | ||
} | ||
|
||
//进行粘包处理 | ||
var off = 0; | ||
var guid = body = ''; | ||
while(total_len > off) { | ||
var len = total_data.getUint32(off); | ||
var data = evt.data.slice(off, off + len + 4); | ||
//解析body | ||
body = Packet.msgunpack(data); | ||
//转发响应的请求 | ||
obj.recvCmd(body); | ||
off += len + 4; | ||
} | ||
|
||
}; | ||
//关闭回调 | ||
ws.onclose = function(evt) { | ||
//断线重新连接 | ||
obj.timer = setInterval(function () { | ||
if(obj.reback_times == 0) { | ||
clearInterval(obj.timer); | ||
clearInterval(Req.timer); | ||
} else { | ||
obj.reback_times--; | ||
obj.webSock(obj.url); | ||
} | ||
},5000); | ||
obj.log('系统提示: 连接断开'); | ||
}; | ||
//socket错误回调 | ||
ws.onerror = function(evt) { | ||
obj.log('系统提示: 服务器错误'+evt.type); | ||
}; | ||
this.ws = ws; | ||
return this; | ||
}, | ||
|
||
//处理消息回调命令字 | ||
recvCmd: function(body) { | ||
console.log('debub data'+body); | ||
console.log(body); | ||
var len = body['len']; | ||
var cmd = body['cmd']; | ||
var scmd = body['scmd']; | ||
var data = body['data']; | ||
this.log('websocket Recv <<< len='+len+" cmd="+cmd+" scmd="+scmd); | ||
//路由到处理地方 | ||
var func = Route[cmd][scmd]; | ||
var str = 'Resp.'+func; | ||
if(func) { | ||
if(typeof(eval(str)) == 'function') { | ||
eval("Resp."+func+"(data)"); | ||
} else { | ||
document.getElementById('msgText').innerHTML += func+':'+JSON.stringify(data) + '\n'; | ||
} | ||
} else { | ||
this.log('func is valid'); | ||
} | ||
|
||
this.log("websocket Recv body <<< func="+func); | ||
this.log(body); | ||
}, | ||
|
||
//打印日志方法 | ||
log: function(msg) { | ||
if(this.dubug) { | ||
console.log(msg); | ||
} | ||
}, | ||
|
||
//发送数据 | ||
send: function(data, cmd, scmd) { | ||
//this.ws.close(); | ||
this.log("websocket Send >>> cmd="+cmd+" scmd="+scmd+" data="); | ||
this.log(data); | ||
var pack_data = Packet.msgpack(data, cmd, scmd); | ||
//组装数据 | ||
if(this.ws.readyState == this.ws.OPEN) { | ||
this.ws.send(pack_data); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
var Packet = { | ||
//jons数据打包成二进制数据 | ||
encode : function(data, cmd, scmd) { | ||
var data = JSON.stringify(data); | ||
var len = data.length + 6; | ||
var buf = new ArrayBuffer(len); // 每个字符占用1个字节 | ||
var buff_data = new DataView(buf, 0, len); | ||
var str_len = data.length; | ||
buff_data.setUint32(0, str_len+2); | ||
buff_data.setUint8(4, cmd); | ||
buff_data.setUint8(5, scmd); | ||
for (var i = 0; i < str_len; i++) { | ||
buff_data.setInt8(i+6, data.charCodeAt(i)); | ||
} | ||
return buf; | ||
}, | ||
|
||
//二进制数据解包成二进制数据 | ||
decode : function(buff) { | ||
var body = ''; | ||
var len = new DataView(buff, 0, 4).getUint32(0); | ||
var body_data = new DataView(buff, 4, len); | ||
//解析cmd | ||
var cmd = body_data.getUint8(0); | ||
var scmd = body_data.getUint8(1); | ||
|
||
//解析body | ||
for(var i = 2; i < body_data.byteLength; i++) { | ||
body += String.fromCharCode(body_data.getUint8(i)); | ||
} | ||
//console.log("data decode >>> len="+len+" cmd="+cmd+" scmd="+scmd+" data="+body); | ||
var body = JSON.parse(body); | ||
body["cmd"] = cmd; | ||
body["scmd"] = scmd; | ||
return body; | ||
}, | ||
|
||
encodeUTF8: function(str){ | ||
var temp = "",rs = ""; | ||
for( var i=0 , len = str.length; i < len; i++ ){ | ||
temp = str.charCodeAt(i).toString(16); | ||
rs += "\\u"+ new Array(5-temp.length).join("0") + temp; | ||
} | ||
return rs; | ||
}, | ||
|
||
decodeUTF8: function(str){ | ||
return str.replace(/(\\u)(\w{4}|\w{2})/gi, function($0,$1,$2){ | ||
return String.fromCharCode(parseInt($2,16)); | ||
}); | ||
}, | ||
|
||
//使用msgpack解包arraybuf数据 | ||
msgunpack: function(buff) { | ||
var body = ''; | ||
var len = new DataView(buff, 0, 4).getUint32(0); | ||
var body_data = new DataView(buff, 4, len); | ||
//解析cmd | ||
var cmd = body_data.getUint8(0); | ||
var scmd = body_data.getUint8(1); | ||
|
||
//解析body | ||
for(var i = 2; i < body_data.byteLength; i++) { | ||
body += String.fromCharCode(body_data.getUint8(i)); | ||
} | ||
//console.log("data msgpack decode >>> cmd="+cmd+" scmd="+scmd+" len="+len+" data="+body); | ||
var body = msgpack.unpack(body); | ||
body["cmd"] = cmd; | ||
body["scmd"] = scmd; | ||
body["len"] = len; | ||
return body; | ||
}, | ||
|
||
//使用packmsg打包object数据对象 | ||
msgpack: function(data, cmd, scmd) { | ||
//var dt = {}; | ||
//dt.data = data; | ||
var data_buff = msgpack.pack(data); | ||
var str_buff = String.fromCharCode.apply(null, new Uint8Array(data_buff)); | ||
var len = str_buff.length + 6; | ||
var buf = new ArrayBuffer(len); // 每个字符占用1个字节 | ||
var buff_data = new DataView(buf, 0, len); | ||
var str_len = str_buff.length; | ||
buff_data.setUint32(0, str_len + 2); | ||
buff_data.setUint8(4, cmd); | ||
buff_data.setUint8(5, scmd); | ||
|
||
for (var i = 0; i < str_len; i++) { | ||
buff_data.setInt8(i+6, str_buff.charCodeAt(i)); | ||
} | ||
//console.log("data msgpack encode >>> cmd="+cmd+" scmd="+scmd+" len="+len+" data="); | ||
//console.log(data); | ||
return buf; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/**发请求命令字处理类*/ | ||
|
||
var Req = { | ||
//定时器 | ||
timer : 0, | ||
|
||
//发送心跳 | ||
heartBeat:function(obj) { | ||
this.timer = setInterval(function () { | ||
if(obj.ws.readyState == obj.ws.OPEN) { | ||
var data = {}; | ||
data['time'] = (new Date()).valueOf() | ||
obj.send(data, MainCmd.CMD_SYS, SubCmd.HEART_ASK_REQ); | ||
} else { | ||
clearInterval(this.timer); | ||
} | ||
}, 600000); | ||
}, | ||
|
||
//游戏开始 | ||
GameStart: function(obj,data) { | ||
var data = {}; | ||
obj.send(data, MainCmd.CMD_GAME, SubCmd.SUB_GAME_START_REQ); | ||
}, | ||
|
||
//抢地主 | ||
GameCall: function(obj,status) { | ||
var data = {"type": status}; | ||
obj.send(data, MainCmd.CMD_GAME, SubCmd.SUB_GAME_CALL_REQ); | ||
}, | ||
|
||
//玩游戏 | ||
PlayGame: function(obj,data) { | ||
obj.send(data, MainCmd.CMD_GAME, SubCmd.SUB_GAME_OUT_CARD_REQ); | ||
}, | ||
|
||
//聊天消息 | ||
ChatMsg: function(obj, data) { | ||
var data = {data}; | ||
obj.send(data, MainCmd.CMD_GAME, SubCmd.CHAT_MSG_REQ); | ||
}, | ||
} |
Oops, something went wrong.