It using the native HTML5 Web Sockets interface / API .
All requests will process through this class and all response will process through this class also
All web-sockets validations / and function dispatching will also triggered from here .
Websockts.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | var WebSocket = WebSocket || window.WebSocket || window.MozWebSocket; var MsgProtocolContainer = function() { this.msgProtocol = new MsgProtocol(); this.msgProtocolGems = new MsgProtocol(); } var WebSocketNode = cc.Node.extend({ m_wsiSendBinary:null, m_loginObj:null, m_GameLayer:null, m_msgProtocolContainer:null, ctor:function () { this._super(); this.winsize = cc.winSize; this.m_msgProtocolContainer = new MsgProtocolContainer(); }, init: function () { this.m_wsiSendBinary = new WebSocket("ws://127.0.0.1:7681/wsapi"); this.m_wsiSendBinary.binaryType = "arraybuffer"; this.m_wsiSendBinary.onopen = function(evt) { cc.log("Send Binary WS was opened."); }; this.m_wsiSendBinary.onmessage = (function(evt) { var binaryUint8 = new Uint8Array(evt.data); var binaryStr = ''; for (var i = 0; i < binaryUint8.length; i++) { binaryStr += String.fromCharCode(binaryUint8[i]); } // cc.log(binaryStr); this.handleServerResponse(binaryStr); this.m_wsiSendBinary.onerror = function(evt) { //this.m_loginObj.serverofflineLabel = 180; cc.log("m_wsiSendBinary Error was fired"); if (cc.sys.isObjectValid(self)) { //self._errorStatus.setString("an error was fired"); cc.log("an error was fired"); } else { cc.log("WebSocket test layer was destroyed!"); } }; this.m_wsiSendBinary.onclose = function(evt) { cc.log("m_wsiSendBinary websocket instance closed."); self.m_wsiSendBinary = null; }; }).bind(this); return true; }, getMsgProtocol:function() { return this.m_msgProtocolContainer; }, handleServerResponse:function(binaryStr) { var ResponseFromServer = Decode(binaryStr); //cc.log(Encode(ResponseFromServer)); switch(ResponseFromServer.status) { case 1: { //cc.log(ResponseFromServer.player_id); this.m_msgProtocolContainer.msgProtocol.player_id = ResponseFromServer.player_id; if(ResponseFromServer.hasOwnProperty("players")) { this.m_msgProtocolContainer.msgProtocol.players = ResponseFromServer.players; } this.m_loginObj.switchToGame(); break; } case 3: { this.m_GameLayer.syncPlayerActions(ResponseFromServer); break; } case 4: { this.m_GameLayer.AddOtherPlayerOnRegister(ResponseFromServer); break; } case 5: { this.m_GameLayer.updateOtherPlayerOnMovment(ResponseFromServer); break; } case 6: { this.m_GameLayer.deletePlayer(ResponseFromServer); break; } case 7: { this.m_msgProtocolContainer.msgProtocolGems.simple_gems = ResponseFromServer.simple_gems; this.m_msgProtocolContainer.msgProtocolGems.bomb_gems = ResponseFromServer.bomb_gems; this.m_msgProtocolContainer.msgProtocolGems.status = ResponseFromServer.status; this.m_msgProtocolContainer.msgProtocolGems.player_id = ResponseFromServer.player_id; this.m_msgProtocolContainer.msgProtocolGems.utc_timestemp = ResponseFromServer.utc_timestemp; break; } } }, _stringConvertToArray:function (strData) { if (!strData) { return null; } var arrData = new Uint16Array(strData.length); for (var i = 0; i < strData.length; i++) { arrData[i] = strData.charCodeAt(i); } return arrData; }, _stringConvertToUint8Array:function (strData) { // View the byte buffer as an array of 8-bit unsigned integers var arrData = new Uint8Array(strData.length); for (var i=0;i<strData.length;++i) { arrData[i] = strData.charCodeAt(i); } // Log the binary array //cc.log("SEND ARRAY BUFFER: " + arrData.buffer); return arrData; }, sendMassage: function(reqJson,_obj) { this.setObjByStatus(_obj,reqJson,reqJson.status); if (this.m_wsiSendBinary.readyState == WebSocket.OPEN) { // cc.log("Send Binary WS is waiting..."); var buf = Encode(reqJson); //cc.log("FROM CLIENT:"+buf); //console.log("PLAYER SEND:"+reqJson.player_name+" x:"+reqJson.player_x); //cc.log("PLAYER SEND X:"+reqJson.player_name+" x:"+reqJson.player_x); //cc.log("PLAYER SEND Y:"+reqJson.player_name+" y:"+reqJson.player_y); var binary = this._stringConvertToUint8Array(buf); if(reqJson.status==2) { var buf1 = Encode(reqJson); cc.log("FROM CLIENT reqJson.status==2:"+buf1); } else if(reqJson.status==8) { var buf1 = Encode(reqJson); cc.log("FROM CLIENT reqJson.status==8:"+buf1); } this.m_wsiSendBinary.send(binary.buffer); } else { var warningStr = "send binary websocket instance wasn't ready...try again in few seconds"; cc.log(warningStr); this.init(); } }, setObjByStatus: function(_obj,_reqJson,_status) { switch(_status) { case 0 : { this.m_msgProtocolContainer.msgProtocol.player_name = _reqJson.player_name; this.m_msgProtocolContainer.msgProtocol.end_player_pos_x=this.winsize.width / 2; this.m_msgProtocolContainer.msgProtocol.end_player_pos_y=this.winsize.height / 2; this.m_loginObj = _obj; break; } case 2 : { this.m_msgProtocolContainer.msgProtocol.player_x = _reqJson.player_x; this.m_msgProtocolContainer.msgProtocol.player_y = _reqJson.player_y; this.m_msgProtocolContainer.msgProtocol.player_seq = _reqJson.player_seq; this.m_msgProtocolContainer.msgProtocol.status = _reqJson.status; this.m_GameLayer = _obj; break; } case 100 : { this.m_GameLayer = _obj; break; } } } }); |
Lines 1 : this is Cocos2d-x declaration to support cross device web sockets
on the web it is naive HTML5 , in desktop and mobile it is libwebsockets , which we are using in the server also .
Lines 18 -23: Initialize the WebSocket HTML 5 object with the Server ip and port in the constructor
Notice we using the wsapi uri as in our server protocol API name < MEIRY todo link >
We set the massaging type to be binary type for speed .
Also setting the WebSocket onopen listener which is triggered when the connection is successful .
Lines 25 -32: When massage Arived from the server it is coming as binary format , which we need to parse back to text format ,
Then the text massage will be send to handleServerResponse function which is well .. handle the responses (:
Lines 60 - 109: This is the response handler function which based on the game protocol state received
The action is chosen . the function are invoked in the Gamelayer object .
Lines 134 - 167: this function will send the request to the server but before that it will convert the text massage to binary type . line 146 . and if there are modifications to be done based on the protocol state this is the place they will happen . lines 157 and 147.
Continue to PART 6 client code where we examine GameLayer.js
i have had numerous requests and appeals from students on who wanted best dissertation that majorly adressed such programming languages i will refer a couple my it savy friends to your blog
ReplyDelete