ws.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import store from "@/store";
  2. import { Message } from "iview";
  3. import { VUE_APP_WK_SERVER_SOCKET_FOR_AUDIO } from "@/constants/constants";
  4. let ws;
  5. let shouldReconnect = true;
  6. let heartbeatId = null;
  7. const RECONNECT_INTERVAL = 3000;
  8. const HEARTBEAT_INTERVAL = 50 * 1000;
  9. let reconnectNumber = 0;
  10. export function openWS({ examRecordDataId }) {
  11. window._hmt.push(["_trackEvent", "websocket", "准备连接"]);
  12. console.log("in openWS", examRecordDataId);
  13. ws = new WebSocket(
  14. VUE_APP_WK_SERVER_SOCKET_FOR_AUDIO +
  15. `${examRecordDataId}/${store.state.user.key}/${store.state.user.token}`
  16. );
  17. ws.onopen = event => {
  18. console.log("open ws", event);
  19. reconnectNumber = 0;
  20. ws.onmessage = processWSMessage;
  21. ws.onclose = () => {
  22. console.log("ws close by server");
  23. clearInterval(heartbeatId);
  24. if (shouldReconnect) {
  25. console.log("close -> reconnect");
  26. setTimeout(() => {
  27. // tryWSReconnect();
  28. reconnectNumber++;
  29. if (reconnectNumber >= 5) {
  30. reconnectNumber = 0;
  31. Message.error({
  32. content: "Websocket重连失败",
  33. duration: 5,
  34. closable: true,
  35. });
  36. }
  37. window._hmt.push([
  38. "_trackEvent",
  39. "websocket",
  40. "连接被关闭后-准备连接",
  41. ]);
  42. openWS({ examRecordDataId });
  43. }, RECONNECT_INTERVAL);
  44. } else {
  45. shouldReconnect = true; // reset shouldReconnect
  46. }
  47. };
  48. heartbeat();
  49. };
  50. ws.onerror = () => {
  51. setTimeout(() => {
  52. reconnectNumber++;
  53. if (reconnectNumber >= 5) {
  54. reconnectNumber = 0;
  55. Message.error({
  56. content: "Websocket重连失败",
  57. duration: 5,
  58. closable: true,
  59. });
  60. }
  61. window._hmt.push(["_trackEvent", "websocket", "连接错误后-重新连接"]);
  62. openWS({ examRecordDataId });
  63. }, RECONNECT_INTERVAL);
  64. };
  65. }
  66. // function tryWSReconnect() {
  67. // // socket.close();
  68. // openWS();
  69. // }
  70. function heartbeat() {
  71. heartbeatId = setInterval(() => {
  72. ws.send(
  73. JSON.stringify({
  74. eventType: "HEARTBEAT",
  75. })
  76. );
  77. }, HEARTBEAT_INTERVAL);
  78. }
  79. export function closeWsWithoutReconnect() {
  80. shouldReconnect = false;
  81. ws.close();
  82. }
  83. export function getQRCode(order) {
  84. if (ws.readyState === ws.OPEN) {
  85. ws.send(
  86. JSON.stringify({
  87. eventType: "GET_QR_CODE",
  88. order,
  89. })
  90. );
  91. return true;
  92. } else {
  93. return false;
  94. }
  95. }
  96. function processWSMessage(event) {
  97. // console.log("get ws msg: ", event);
  98. const res = JSON.parse(event.data);
  99. if (res.eventType !== "HEARTBEAT" && !res.isSuccess) {
  100. Message.error({
  101. content: res.errorMessage,
  102. duration: 10,
  103. closable: true,
  104. });
  105. return;
  106. }
  107. switch (res.eventType) {
  108. case "HEARTBEAT":
  109. // console.log("ws heartbeat response from server");
  110. break;
  111. case "GET_QR_CODE":
  112. console.log("get qrcode", res);
  113. window._hmt.push(["_trackEvent", "websocket", "获得二维码"]);
  114. store.commit("examingHomeModule/setQuestionQrCode", {
  115. qrCode: res.data.qrCode,
  116. order: res.data.order,
  117. });
  118. break;
  119. case "SCAN_QR_CODE":
  120. console.log("wx scanned qrcode", res);
  121. window._hmt.push(["_trackEvent", "websocket", "二维码被扫描"]);
  122. store.commit("examingHomeModule/setQuestionQrCodeScanned", {
  123. order: res.data.order,
  124. });
  125. break;
  126. case "GET_AUDIO_ANSWER":
  127. console.log("get audio url", res);
  128. window._hmt.push(["_trackEvent", "websocket", "获得音频地址"]);
  129. store.commit("examingHomeModule/setQuestionAudioFileUrl", {
  130. order: res.data.order,
  131. audioFileUrl: res.data.audioFileUrl,
  132. });
  133. break;
  134. case "SYSTEM_ERROR":
  135. console.log("ws get error", res);
  136. break;
  137. }
  138. }