Socket.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import Heartbeat from "./Heartbeat.js"
  2. import Timeout from "./Timeout.js"
  3. import InitNetworkTimeoutError from "./error/InitNetworkTimeoutError.js"
  4. import {reporter} from "./Reporter.js"
  5. import util from "./util.js"
  6. import InternalError from "./error/InternalError.js"
  7. import Logger from "./Logger.js"
  8. const logger = new Logger('ws')
  9. export default class Socket extends EventEmitter {
  10. constructor(e) {
  11. super();
  12. E(this, "_ws");
  13. E(this, "_openTimer");
  14. E(this, "connected", !1);
  15. E(this, "_hasTimeout", !1);
  16. E(this, "heartbeat");
  17. E(this, "latency", (e,t)=>this.send({
  18. id: "checkLatency",
  19. data: JSON.stringify(e),
  20. packet_id: t
  21. }));
  22. E(this, "send", e=>{
  23. if (this.wsNoReady())
  24. {
  25. return;
  26. }
  27. const t = JSON.stringify(e);
  28. e.id !== "heartbeat" && logger.info("send ws frame", t);
  29. this._ws.send(t);
  30. console.log('发送socket数据:'+t)
  31. }
  32. );
  33. E(this, "startGame", ()=>{
  34. const {roomId: e, userId: t, avatarId: r, skinId: n, role: o, avatarComponents: a, versionId: s, rotationRenderType: l, isAllSync: u, nickname: c, avatarScale: h, appId: f, camera: d, player: _, firends: g, syncByEvent: m, areaName: v, attitude: y, pathName: b, person: T, roomTypeId: C="", syncToOthers: A, hasAvatar: S, prioritySync: P, extra: R={}, removeWhenDisconnected: M} = this.network.room.currentNetworkOptions;
  35. R.removeWhenDisconnected = M;
  36. const x = {
  37. id: "start",
  38. room_id: e,
  39. user_id: t,
  40. trace_id: util.uuid(),
  41. data: JSON.stringify({
  42. avatar_components: JSON.stringify(a),
  43. avatar_id: r,
  44. skin_id: n,
  45. is_host: o ? o == "host" : !0,
  46. skin_data_version: n !== void 0 && s !== void 0 ? n + s : void 0,
  47. rotation_render_type: l,
  48. is_all_sync: u,
  49. nick_name: encodeURIComponent(c || ""),
  50. app_id: f,
  51. camera: d,
  52. player: _,
  53. person: T,
  54. firends: JSON.stringify(g),
  55. sync_by_event: m,
  56. area_name: v,
  57. path_name: b,
  58. attitude: y,
  59. room_type_id: C,
  60. syncToOthers: A,
  61. hasAvatar: S,
  62. avatarSize: h,
  63. prioritySync: P,
  64. extra: JSON.stringify(R)
  65. })
  66. };
  67. //this.send(x);
  68. // logger.warn("startGame", le(oe({}, x), {
  69. // data: JSON.parse(x.data)
  70. // }))
  71. }
  72. );
  73. this.network = e;
  74. // this.heartbeat = new Heartbeat({
  75. // ping: t=>{
  76. // var r;
  77. // if (!this.connected) {
  78. // this.heartbeat.stop(),
  79. // (r = e.room.stats) == null || r.assign({
  80. // rtt: 0
  81. // });
  82. // return
  83. // }
  84. // this.send({
  85. // id: "heartbeat",
  86. // data: t
  87. // })
  88. // }
  89. // ,
  90. // pong(t) {
  91. // var r;
  92. // (r = e.room.stats) == null || r.assign({
  93. // rtt: t
  94. // })
  95. // }
  96. // })
  97. }
  98. get connection() {
  99. return this._ws
  100. }
  101. start() {
  102. this._hasTimeout = !1;
  103. const e = this.getAddress();
  104. logger.info(`connecting to ${e}`);
  105. const t = Date.now();
  106. // this._ws = new WebSocket(e);
  107. // this._openTimer = new Timeout(()=>{
  108. // const r = `Failed to open websocket in ${DEFAULT_OPEN_TIMEOUT_MS} ms`;
  109. // this._hasTimeout = !0,
  110. // this.emit("socketClosed", new InitNetworkTimeoutError(r))
  111. // },DEFAULT_OPEN_TIMEOUT_MS),
  112. // this._ws.onopen = ()=>{
  113. // var r;
  114. // (r = this._openTimer) == null || r.clear(),
  115. // this.connected = !0,
  116. // this.heartbeat.start(),
  117. // this.network.room.currentNetworkOptions.reconnect || (logger.infoAndReportMeasurement({
  118. // metric: "wsOpenedAt",
  119. // group: "joinRoom",
  120. // startTime: this.network.room._startTime
  121. // }),
  122. // logger.infoAndReportMeasurement({
  123. // metric: "wsOpenedCost",
  124. // group: "joinRoom",
  125. // startTime: t
  126. // }))
  127. // },
  128. this.connected = !0;
  129. //this.handleWSEvent()
  130. }
  131. getAddress() {
  132. const {wsServerUrl: e, reconnect: t, sessionId: r, token: n, roomId: o, userId: a, pageSession: s} = this.network.room.currentNetworkOptions
  133. , l = this.network.room.skinId;
  134. let u = e;
  135. t && (u = u + `?reconnect=true&lastSessionID=${r}`);
  136. const c = `userId=${a}&roomId=${o}&pageSession=${s}` + (this.network.room.isHost ? `&skinId=${l}` : "") + (n ? `&token=${n}` : "");
  137. return u = u.indexOf("?") > -1 ? u + "&" + c : u + "?" + c,
  138. u
  139. }
  140. handleWSEvent() {
  141. const e = this._ws;
  142. e.addEventListener("error", t=>{
  143. this.connected = !1,
  144. logger.error("webscoket error", t),
  145. this.emit("socketClosed", new InternalError("connect to address error: " + this.network.room.currentNetworkOptions.wsServerUrl))
  146. }
  147. ),
  148. e.addEventListener("close", t=>{
  149. this.connected = !1,
  150. this._onClose(t)
  151. }
  152. ),
  153. e.addEventListener("message", t=>{
  154. if (!t || this._hasTimeout || !this.connected)
  155. return;
  156. let r = null;
  157. try {
  158. r = JSON.parse(t.data)
  159. console.log('接收socket数据:'+t.data)
  160. } catch (o) {
  161. logger.error(o);
  162. return
  163. }
  164. if (!r)
  165. return;
  166. const n = r.id;
  167. if (!!n)
  168. {
  169. n !== "heartbeat" && logger.info(`receive ws frame: ${t.data}`);
  170. switch (n) {
  171. case "fail":
  172. break;
  173. case "init":
  174. // try {
  175. // const o = r.data.slice(-37, -1);
  176. // reporter.updateBody({
  177. // serverSession: o
  178. // })
  179. // } catch (o) {
  180. // console.error(o)
  181. // }
  182. // this.network.rtcp.start();
  183. break;
  184. // case "heartbeat":
  185. // this.heartbeat.pong(r.data);
  186. // break;
  187. case "offer":
  188. //this.network.rtcp.setRemoteDescription(r.data, this.network.stream.el);
  189. break;
  190. case "ice_candidate":
  191. //this.network.rtcp.addCandidate(r.data);
  192. break;
  193. // case "start":
  194. // this.emit("gameRoomAvailable", r);
  195. // break;
  196. // case "error":
  197. // try {
  198. // const {Code: o, Msg: a} = JSON.parse(r.data);
  199. // if (o) {
  200. // if (o == 3003)
  201. // return this.emit("socketClosed", new TokenExpiredError);
  202. // if (authenticationErrorCodes.indexOf(o) > -1)
  203. // return this.emit("socketClosed", new AuthenticationError("\u9274\u6743\u9519\u8BEF:" + a));
  204. // {
  205. // const s = util.getErrorByCode(o);
  206. // this.emit("socketClosed", new s(a))
  207. // }
  208. // }
  209. // } catch (o) {
  210. // logger.error(o),
  211. // this.emit("socketClosed", new InternalError(r.data))
  212. // }
  213. // break;
  214. // case "checkLatency":
  215. // {
  216. // const o = r.packet_id
  217. // , a = r.data.split(",");
  218. // this.onLatencyCheck({
  219. // packetId: o,
  220. // addresses: a
  221. // });
  222. // break
  223. // }
  224. // default:
  225. // logger.warn("unkown ws message type", n, r)
  226. }
  227. }
  228. }
  229. )
  230. }
  231. onLatencyCheck(e) {
  232. const t = [...new Set(e.addresses || [])];
  233. Promise.all(t.map(r=>({
  234. [r]: 9999
  235. }))).then(r=>{
  236. const n = Object.assign({}, ...r);
  237. this.latency(n, e.packetId)
  238. }
  239. )
  240. }
  241. wsNoReady() {
  242. return this._ws.readyState == WebSocket.CLOSED || this._ws.readyState == WebSocket.CLOSING || this._ws.readyState == WebSocket.CONNECTING
  243. }
  244. prepareReconnect() {
  245. this._close({
  246. code: WS_CLOSE_RECONNECT,
  247. reason: "reconnect"
  248. })
  249. }
  250. _onClose({code: e, reason: t}) {
  251. this._openTimer && this._openTimer.clear(),
  252. logger.warn(`ws closed: ${e} ` + t),
  253. [WS_CLOSE_RECONNECT, WS_CLOSE_NORMAL].includes(e) || this.emit("socketClosed", new InternalError("Websocket error"))
  254. }
  255. _close({code: e, reason: t}) {
  256. var r;
  257. (r = this._ws) == null || r.close(e, t)
  258. }
  259. quit() {
  260. this._close({
  261. code: WS_CLOSE_NORMAL,
  262. reason: "quit"
  263. })
  264. }
  265. }