LoginMgr.js 16 KB

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