NetManager.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import { FrameworkConf } from "../../framework/config/FrameworkConf";
  2. import { Framework } from "../../framework/Framework";
  3. import { GameEvent } from "../data/GameEvent";
  4. import { StringUtil } from "../../framework/util/StringUtil";
  5. import { ViewID } from "../../framework/config/LayerConf";
  6. export let NetMgr: NetManager = null;
  7. export class NetManager {
  8. private _socket: WebSocket = null;
  9. private _web_url = ""; //服务器地址
  10. private _callback: Function = null;
  11. private _hear_time = 5; //心跳时间
  12. private _hear_time_out = 2; //心跳超次数()
  13. private _hear_time_cur = 0; //心跳超时次数
  14. private _hear_uuid = 0; //心跳定时器
  15. private _is_connect = false; //网络是否连接
  16. private _bReconnect = false; //是否重连
  17. private _bHandShake = false; //是否握手
  18. private _bProClose = false; //是否主动断开
  19. private _uid = 0;
  20. private _seq = 0;
  21. //心跳超时 自动重连,超过5次则不再重连
  22. private _auto_reconnect_time = 0;
  23. private _auto_reconnect_time_out = 5;
  24. private _socketId = 0;
  25. static get instance() {
  26. if (NetMgr == null) {
  27. NetMgr = new NetManager();
  28. }
  29. return NetMgr;
  30. }
  31. //网络是否连接
  32. get is_connect() {
  33. return this._is_connect;
  34. }
  35. get is_handShake() {
  36. return this._bHandShake;
  37. }
  38. get bReconnect() {
  39. return this._bReconnect;
  40. }
  41. get bProClose() {
  42. return this._bProClose;
  43. }
  44. connect(url: string, callback: Function) {
  45. //this.close(false);
  46. let socketId = ++this._socketId
  47. this._clearHeart();
  48. this._web_url = url;
  49. this._callback = callback;
  50. this._socket = new WebSocket(this._web_url, 'default-protocol');
  51. this._socket.binaryType = "arraybuffer";
  52. this._socket.onopen = (event: any) => {
  53. if(socketId != this._socketId){
  54. return
  55. }
  56. callback && callback(0);
  57. callback = null;
  58. this._is_connect = true;
  59. this._bProClose = false
  60. this._auto_reconnect_time = 0
  61. this._hear_time_cur = 0
  62. };
  63. this._socket.onerror = (event: any) => {
  64. if(socketId != this._socketId){
  65. return
  66. }
  67. console.log("onerror:", event," socketId:",socketId);
  68. callback && callback(1);
  69. callback = null;
  70. this._is_connect = false;
  71. this._bHandShake = false
  72. this._clearHeart();
  73. // this._socket = null
  74. // this._autoReconnect(3)
  75. Framework.event.fireEvent(FrameworkConf.Event.NET_ERROR, event);
  76. };
  77. this._socket.onclose = (event: any) => {
  78. if(socketId != this._socketId){
  79. return
  80. }
  81. console.log("onclose1:", event," socketId:",socketId);
  82. this._is_connect = false;
  83. this._bHandShake = false
  84. this._bReconnect = false
  85. this._clearHeart();
  86. this._socket = null
  87. Framework.layer.open(ViewID.MaskUI,()=>{});
  88. if(!this._bProClose){
  89. this._autoReconnect(3)
  90. }
  91. else Framework.event.fireEvent(FrameworkConf.Event.NET_CLOSE, event);
  92. };
  93. this._socket.onmessage = (event: any) => {
  94. let Json = JSON.parse(event.data)
  95. // console.log(Json);
  96. if (Json.mod == 'user' && Json.act == 'handshake') {
  97. this._startHeart();
  98. if (Json.code == 0) {
  99. Framework.layer.close(ViewID.MaskUI);
  100. this._bHandShake = true
  101. // if(Framework.layer.getUIView(ViewID.BombUI)){
  102. //window.parent.postMessage(FrameworkConf.Event.NET_RECONNECT, "*");
  103. this._uid = Json.data._id
  104. Framework.event.fireEvent(FrameworkConf.Event.NET_RECONNECT, {});
  105. this._bReconnect = false
  106. //}
  107. // if(!Framework.layer.getUIView(ViewID.BombUI)){
  108. // var args = { 'uid': Json.data._id, 'cash': Json.data.cash, 'state': 1 };
  109. // Framework.layer.open(ViewID.BombUI, null, args);
  110. // }
  111. }else {
  112. this.close(false)
  113. Framework.event.fireEvent(FrameworkConf.Event.NET_HANDSHAKE_ERROR, Json.code);
  114. // 弹窗提示登陆失败
  115. Framework.tips.setTips(Json.desc);
  116. }
  117. }else if (Json.mod == 'user' && Json.act == 'heart_beat') {
  118. this._hear_time_cur = 0;
  119. //console.error(Json)
  120. } else {
  121. if (Json.seq == this._seq) {
  122. // 解开遮罩
  123. }
  124. // console.log("onmessage:",event.data);
  125. Framework.event.fireEvent(FrameworkConf.Event.NET_MSG, Json);
  126. }
  127. };
  128. }
  129. /**
  130. * 关闭socket
  131. * @param bReconnect 是否重连
  132. */
  133. close(bReconnect) {
  134. console.log("close test");
  135. this._socket && this._socket.close();
  136. this._socket = null;
  137. this._is_connect = false;
  138. this._bHandShake = false
  139. this._bProClose = true;
  140. this._clearHeart();
  141. // window.parent.postMessage(FrameworkConf.Event.NET_CLOSE, "*");
  142. if(bReconnect){
  143. Framework.layer.open(ViewID.MaskUI);
  144. this._autoReconnect()
  145. }
  146. else{
  147. Framework.layer.open(ViewID.MaskUI,()=>{},{closeTime:0});
  148. console.error("断开连接")
  149. }
  150. }
  151. send(msg: any) {
  152. //msg.uid = UserData['_id'];
  153. let msgStr = JSON.stringify(msg)
  154. // console.log(msgStr);
  155. // console.log(this._socket);
  156. if (this._socket) {
  157. // // let strBuf = this.protoEncode(cmd, msg);
  158. // // let buf = this.packet(strBuf);
  159. this._socket.send(msgStr)
  160. }
  161. }
  162. // uint8Array转typedArray
  163. typedArray(uint8Array) {
  164. var hex = Array.prototype.map
  165. .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
  166. .join('');
  167. var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
  168. return parseInt(h, 16)
  169. }))
  170. var buffer = typedArray.buffer;
  171. return buffer;
  172. }
  173. private _clearHeart() {
  174. (this._hear_uuid != 0) && Framework.time.unschedule(this._hear_uuid);
  175. this._hear_uuid = 0;
  176. }
  177. private _startHeart() {
  178. this._clearHeart();
  179. this._hear_uuid = Framework.time.schedule(() => {
  180. this._hear_time_cur += 1;
  181. if(this._hear_time_cur > this._hear_time_out){
  182. console.error("心跳超时",this._hear_time_cur);
  183. this.close(true);
  184. //this._autoReconnect()
  185. }
  186. else if (this._socket) {
  187. // this._hear_uuid = 0;
  188. this.netApiSend("user","heart_beat",{});
  189. }
  190. }, this._hear_time);
  191. }
  192. // 自动重连
  193. // delay:延迟时间
  194. private _autoReconnect(delay?:number) {
  195. if(this._bReconnect) {
  196. console.error("自动重连中",new Date());
  197. return
  198. }
  199. if (this._is_connect) {
  200. return;
  201. }
  202. if (this._auto_reconnect_time > this._auto_reconnect_time_out) {
  203. Framework.tips.setTips("Reconnection failed");
  204. console.error("多少次重连失败1")
  205. //window.parent.postMessage(FrameworkConf.Event.NET_ERROR, "*");
  206. Framework.layer.open(ViewID.MaskUI,()=>{},{closeTime:0});
  207. return;
  208. }
  209. delay = delay || 0
  210. if(delay > 0){
  211. Framework.time.scheduleOnce(()=>{
  212. this._autoReconnect()
  213. },delay)
  214. return
  215. }
  216. console.log("自动重连");
  217. this._auto_reconnect_time += 1;
  218. this._bReconnect = true
  219. this.connect(this._web_url,this._callback)
  220. }
  221. netApiSend(mod, act, args) {
  222. let req = {
  223. mod: mod,
  224. act: act,
  225. args: args,
  226. uid: this._uid,
  227. seq: this._seq++,
  228. }
  229. Framework.event.fireEvent('cid', args);
  230. // if(act != "heart_beat"){
  231. // console.log("发送", req);
  232. // }
  233. this.send(req);// 握手消息,返回在netmanger里面处理
  234. // 启动loading 遮罩id
  235. }
  236. }