LoginMgr.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /**
  2. * 登录数据管理
  3. */
  4. let LoginMgr = {
  5. //* ************* 初始化 ************* *//
  6. /**
  7. * 初始化
  8. *
  9. */
  10. init () {
  11. if (CC_EDITOR) {
  12. return;
  13. }
  14. // 注册消息
  15. G.PublicMgr.on(JMC.PUBLIC_MSG.SWITCH_ACCOUNT, JMC.PUBLIC_MSG_ORDER.LOGIN, this.handleDidSwitchAccount, this);
  16. G.PublicMgr.on(JMC.PUBLIC_MSG.LOGIN_SUCCESS, JMC.PUBLIC_MSG_ORDER.LOGIN, this.handleDidLoginSuccess, this);
  17. G.PublicMgr.on(JMC.PUBLIC_MSG.DISCONNECTED, JMC.PUBLIC_MSG_ORDER.LOGIN, this.handleDidDisconnected, this);
  18. this._initEventListener();
  19. this._initPublishListener();
  20. cc.game.on('e_mgr_load_config_done', this.initLocalConfig, this);
  21. cc.game.on('e_middle_auth_logout_result', this._handleAuthLogoutResult, this);
  22. },
  23. /**
  24. * 初始化事件侦听
  25. *
  26. */
  27. _initEventListener () {
  28. cc.game.on('e_socket_on_connected', this._handleSocketOnConected, this);
  29. cc.game.on('e_socket_on_closed', this._handleSocketOnClosed, this);
  30. cc.game.on('e_mgr_conf_download_result', this.handleConfDownloadResult, this);
  31. },
  32. /**
  33. * 初始化服务器请求事件侦听
  34. *
  35. */
  36. _initPublishListener () {
  37. },
  38. /**
  39. * 初始化本地配置
  40. *
  41. */
  42. initLocalConfig () {
  43. },
  44. /**
  45. * 离线
  46. *
  47. */
  48. offline () {
  49. // 容错:避免前面没有关闭socket,这里再关闭一次
  50. // closeSocket有非空判断,正常情况下不会有任何效果
  51. G.NetworkMgr.closeSocket();
  52. // 向各个Mgr发送断线消息
  53. G.PublicMgr.emit(JMC.PUBLIC_MSG.DISCONNECTED);
  54. },
  55. //* ************* 事件侦听 ************* *//
  56. _handleSocketOnConected () {
  57. this._stopKeepalive();
  58. // 请求授权令牌
  59. this.requestAuthToken();
  60. },
  61. /**
  62. * 收到登录成功事件
  63. *
  64. */
  65. handleDidLoginSuccess () {
  66. // 标记在线状态
  67. this.isOnline = true;
  68. // 重连计数重置
  69. this.reconnectTimes = 0;
  70. // h5user_self_info on_h5user_system_info都收到
  71. cc.game.emit('e_socket_on_logined');
  72. },
  73. /**
  74. * 收到断网事件
  75. *
  76. */
  77. handleDidDisconnected () {
  78. this.isOnline = false;
  79. },
  80. /**
  81. * 收到切换账号事件
  82. *
  83. */
  84. handleDidSwitchAccount () {
  85. },
  86. /**
  87. * 中间层注销账号
  88. *
  89. */
  90. _handleAuthLogoutResult (eventData) {
  91. // eventData.data // 授权信息
  92. // 关闭websocket链接
  93. this.offline();
  94. cc.director.loadScene('scene_login');
  95. },
  96. //* ************* 客户端请求/响应 ************* *//
  97. /**
  98. * 请求注册
  99. *
  100. */
  101. // #注册
  102. // usr_register 1001 {
  103. // request {
  104. // version 1: string # 版本号
  105. // uuid 2: string # UUID
  106. // device 3: string # 设备名称
  107. // sysVer 4: string # 设备信息
  108. // channel 5: integer # 渠道号
  109. // apn 6: string # 玩家网络状态
  110. // operator 7: string # 运营商类型字段
  111. // platform 8: string # 登录平台
  112. // udid 9: string # UDID
  113. // appVerison 10: string # 对内版本号
  114. // deviceId 11: string # 设备号
  115. // }
  116. // response {
  117. // code 0: integer
  118. // sysTime 1: integer # 服务器时间
  119. // ip 2: string # Socket连接的IP
  120. // port 3: integer # Socket连接的Port
  121. // token 4: string # token
  122. // uid 5: integer #
  123. // password 6: string # 密码
  124. // http 7: integer # HTTP PORT
  125. // registerTime 8: integer # 注册时间
  126. // errorMsg 9: string # 登陆失败错误信息
  127. // isGuest 10: boolean # 是否游客
  128. // wsPort 11: integer # websocket连接端口
  129. // uuid 12: string # UUID
  130. // configVersion 13: string # configVersion
  131. // }
  132. // }
  133. requestRegister () {
  134. let info = {
  135. version: G.MiddleMgr.getVersion(),
  136. uuid: G.MiddleMgr.getUUID(),
  137. device: G.MiddleDevice.getDeviceName() + G.FuncUtils.randomInt(100000, 999999),
  138. sysVer: G.MiddleDevice.getDeviceInfo(),
  139. channel: G.MiddleDevice.getChannelId(),
  140. apn: G.MiddleDevice.getApnType(),
  141. operator: G.MiddleDevice.getOperator(),
  142. platform: cc.sys.platform,
  143. udid: G.MiddleMgr.getUDID(),
  144. appVerison: G.APP_VERSION,
  145. deviceId: G.MiddleMgr.getIDFAEncode(),
  146. };
  147. G.NetworkMgr.sendHttpRequestToLoginServer('usr_register', info, this._responseLogin.bind(this));
  148. },
  149. // # 注册 - 手机号
  150. // usr_register_by_phone 1002 {
  151. // request {
  152. // version 1: string # 必填 - 版本号
  153. // channel 2: integer # 必填 - 渠道号
  154. // device 3: string # 选填 - 设备名称
  155. // sysVer 4: string # 选填 - 设备信息
  156. // apn 5: string # 选填 - 玩家网络状态
  157. // operator 6: string # 选填 - 运营商类型字段
  158. // platform 7: string # 选填 - 登录平台
  159. // deviceId 8: string # 选填 - 设备号
  160. // phone 30: string # 必填 - 手机号
  161. // vcode 31: string # 必填 - 验证码
  162. // password 32: string # 必填 - 密码
  163. // nickname 33: string # 选填 - 昵称 - 空:手机号作为昵称
  164. // sharecode 34: string # 选填 - 邀请码
  165. // }
  166. // response {
  167. // code 0: integer
  168. // sysTime 1: integer # 服务器时间
  169. // ip 2: string # 游戏服网关地址
  170. // port 3: integer # 网关Socket连接的Port
  171. // wsPort 4: integer # 网关websocket连接端口
  172. // httpPort 5: integer # 网关HTTP PORT
  173. // token 6: string # token
  174. // uid 7: integer # 玩家id
  175. // registerTime 8: integer # 注册时间
  176. // errorMsg 9: string # 登陆失败错误信息
  177. // configVersion 10: string # configVersion
  178. // }
  179. // }
  180. requestRegisterByPhone (phone, password, nickname, sharecode) {
  181. let info = {
  182. version: G.MiddleMgr.getVersion(),
  183. channel: G.MiddleDevice.getChannelId(),
  184. phone: phone,
  185. vcode: "",
  186. password: password,
  187. nickname: nickname ? nickname : "",
  188. sharecode: sharecode ? sharecode : ""
  189. };
  190. G.NetworkMgr.sendHttpRequestToLoginServer('usr_register_by_phone', info, this._responseLogin.bind(this));
  191. },
  192. /**
  193. * 请求登录
  194. *
  195. * @param {string} uid 用户ID
  196. * @param {string} password 用户密码
  197. */
  198. // #登录
  199. // usr_login 1000 {
  200. // request {
  201. // uid 0: integer
  202. // version 1: string # 版本号
  203. // password 2: string # 密码
  204. // channel 3: integer # 渠道号
  205. // apn 4: string # 玩家网络状态
  206. // operator 5: string # 运营商类型字段
  207. // platform 6: string # 登录平台
  208. // appVerison 7: string # 对内版本号
  209. // uuid 8: string # UUID
  210. // udid 9: string # UDID
  211. // sysVer 10: string # 设备信息
  212. // }
  213. // response {
  214. // code 0: integer
  215. // sysTime 1: integer # 服务器时间
  216. // ip 2: string # Socket连接的IP
  217. // port 3: integer # Socket连接的Port
  218. // token 4: string # token
  219. // http 5: integer # HTTP PORT
  220. // registerTime 6: integer # 注册时间
  221. // errorMsg 7: string # 登陆失败错误信息
  222. // isGuest 8: boolean # 是否游客
  223. // wsPort 9: integer # websocket连接端口
  224. // uuid 10: string # UUID
  225. // configVersion 11: string # configVersion
  226. // }
  227. // }
  228. requestLogin (uid, password) {
  229. let info = {
  230. uid: uid,
  231. version: G.MiddleMgr.getVersion(),
  232. password: password,
  233. channel: G.MiddleDevice.getChannelId(),
  234. apn: G.MiddleDevice.getApnType(),
  235. operator: G.MiddleDevice.getOperator(),
  236. platform: cc.sys.platform,
  237. appVerison: G.APP_VERSION,
  238. udid: G.MiddleMgr.getUDID(),
  239. uuid: G.MiddleMgr.getUUID(),
  240. sysVer: G.MiddleDevice.getDeviceInfo(),
  241. };
  242. G.NetworkMgr.sendHttpRequestToLoginServer('usr_login', info, this._responseLogin.bind(this));
  243. },
  244. // # 登录 - 手机号
  245. // usr_login_by_phone 1003 {
  246. // request {
  247. // version 1: string # 必填 - 版本号
  248. // channel 2: integer # 必填 - 渠道号
  249. // device 3: string # 选填 - 设备名称
  250. // sysVer 4: string # 选填 - 设备信息
  251. // apn 5: string # 选填 - 玩家网络状态
  252. // operator 6: string # 选填 - 运营商类型字段
  253. // platform 7: string # 选填 - 登录平台
  254. // deviceId 8: string # 选填 - 设备号
  255. // phone 30: string # 必填 - 手机号
  256. // vcode 31: string # vcode/password必填 - 验证码 - 优先校验vcode
  257. // password 32: string # vcode/password必填 - 密码
  258. // }
  259. // response {
  260. // code 0: integer
  261. // sysTime 1: integer # 服务器时间
  262. // ip 2: string # 游戏服网关地址
  263. // port 3: integer # 网关Socket连接的Port
  264. // wsPort 4: integer # 网关websocket连接端口
  265. // httpPort 5: integer # 网关HTTP PORT
  266. // token 6: string # token
  267. // uid 7: integer # 玩家id
  268. // registerTime 8: integer # 注册时间
  269. // errorMsg 9: string # 登陆失败错误信息
  270. // configVersion 10: string # configVersion
  271. // }
  272. // }
  273. requestLoginByPhone (phone, password) {
  274. let info = {
  275. version: G.MiddleMgr.getVersion(),
  276. channel: G.MiddleDevice.getChannelId(),
  277. phone: phone,
  278. password: password
  279. };
  280. G.NetworkMgr.sendHttpRequestToLoginServer('usr_login_by_phone', info, this._responseLogin.bind(this));
  281. },
  282. /**
  283. * 注册和登录的回调
  284. * 登录和注册返回的数据唯一不同是
  285. * 注册多了uid 和 password
  286. *
  287. * @author libo
  288. * @date 2019-06-19
  289. * @param {object} data
  290. */
  291. _responseLogin (data) {
  292. let requestInfo = data.requestInfo;
  293. let responseInfo = data.responseInfo;
  294. switch (responseInfo.code) {
  295. case 200: // 成功d
  296. case 2010: // 已经注册了的用户
  297. {
  298. if (responseInfo.sysTime && responseInfo.sysTime > 0) {
  299. G.TimeUtils.synTime(responseInfo.sysTime);
  300. }
  301. // 记录登录成功时间
  302. this.loginTimestamp = G.TimeUtils.getCurrentTime();
  303. // 特殊处理uid和password
  304. let uid = (responseInfo.uid) ? responseInfo.uid : requestInfo.uid;
  305. let password = (responseInfo.password) ? responseInfo.password : requestInfo.password;
  306. // 设置uid
  307. uid = parseInt(uid);
  308. G.UserMgr.setUid(uid);
  309. this.loginData = responseInfo;
  310. this.loginData.uid = uid;
  311. this.loginData.password = password;
  312. this._connectGameServer(responseInfo.ip, responseInfo.wsPort || responseInfo.http);
  313. break;
  314. }
  315. case 2004: // 密码错误
  316. {
  317. break;
  318. }
  319. case 2009: // 账号被封杀
  320. {
  321. break;
  322. }
  323. default: // 参数错误 或 未知错误
  324. {
  325. // 连接错误或者连接错误会返回 400
  326. break;
  327. }
  328. }
  329. // 将消息下发到ctrl中处理
  330. cc.game.emit('e_nwk_usr_login', data);
  331. },
  332. /**
  333. * 请求授权令牌
  334. *
  335. * @author Wetion
  336. * @date 2019-03-26
  337. */
  338. requestAuthToken () {
  339. let info = {
  340. uid: this.loginData.uid,
  341. token: this.loginData.token
  342. };
  343. G.NetworkMgr.sendSocketRequest('usr_auth_token', info, this._responseAuthToken.bind(this));
  344. },
  345. _responseAuthToken (data) {
  346. let responseInfo = data.responseInfo;
  347. if (responseInfo.code === 200) {
  348. this.keepaliveTime = this.loginData.sysTime;
  349. this._startKeepalive();
  350. G.UserMgr.requestSelfInfo();
  351. }
  352. },
  353. // 启动心跳,4 * 30秒后发出第一条心跳
  354. _startKeepalive () {
  355. this._stopKeepalive();
  356. this.keepaliveTimeoutCount = 0;
  357. this._keepaliveIntervalId = setInterval(() => {
  358. this.keepaliveTimeoutCount++;
  359. /**
  360. * 定时器30秒执行一次
  361. * 4 * 30秒间隔发一次保活请求
  362. * 发送保活请求后30秒没返回断开当前连接进行重连
  363. */
  364. if (this.keepaliveTimeoutCount == 4) {
  365. // G.LogUtils.log('发送心跳');
  366. this._requestKeepalive();
  367. } else if (this.keepaliveTimeoutCount == 5) {
  368. // G.LogUtils.log('心跳不通');
  369. // 清空心跳定时器
  370. clearInterval(this._keepaliveIntervalId);
  371. this._keepaliveIntervalId = undefined;
  372. // 断开网络并且弹出重连窗口
  373. G.NetworkMgr.closeSocket();
  374. G.AppUtils.getSceneCtrl().showOfflineAlert();
  375. }
  376. }, 30 * 1000);
  377. },
  378. /**
  379. * 连接保活, 客户端主动60s发送一次
  380. *
  381. * @author Wetion
  382. * @date 2019-03-26
  383. */
  384. _requestKeepalive () {
  385. G.NetworkMgr.sendSocketRequest('h5user_keepalive', undefined, this._responseKeepalive.bind(this));
  386. },
  387. _responseKeepalive (data) {
  388. let responseInfo = data.responseInfo;
  389. if (responseInfo && responseInfo.systemTime) {
  390. this.keepaliveTime = responseInfo.systemTime;
  391. // 间隔多少秒请求一次保活
  392. this.keepaliveTimeoutCount = 0;
  393. }
  394. },
  395. // 重置心跳定时器
  396. _stopKeepalive () {
  397. if (this._keepaliveIntervalId) {
  398. clearInterval(this._keepaliveIntervalId);
  399. this._keepaliveIntervalId = undefined;
  400. }
  401. },
  402. _connectGameServer (host, port) {
  403. // 链接SOCKET
  404. G.NetworkMgr.connectSocket(host, port);
  405. // 增加HTTP_GAME连接
  406. G.NetworkMgr.addConnection({
  407. alias: '游戏服',
  408. name: 'HTTP_GAME',
  409. host: host,
  410. port: port,
  411. path: 'pb'
  412. });
  413. },
  414. }
  415. module.exports = LoginMgr;