websocket.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import useUserStore from '@/store/modules/user';
  2. import { getToken } from '@/utils/auth';
  3. let webSock = null;
  4. let connectState = false; // 标记 WebSocket 连接状态
  5. let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码
  6. let closeFlag = false; // 是否关闭socket
  7. let global_callback = null;
  8. const port = '9988'; // webSocket连接端口
  9. const useUser = useUserStore();
  10. const wsUrl = `${import.meta.env.VITE_APP_BASE_WEBSOCKET}/api/pattern/1/ws`;
  11. function createWebSocket(callback) {
  12. if (webSock != null) {
  13. return;
  14. }
  15. webSock = new WebSocket(wsUrl);
  16. global_callback = callback;
  17. webSock.onopen = function () {
  18. // 连接打开时的处理
  19. websocketOpen();
  20. };
  21. webSock.onmessage = function (e) {
  22. // 接收消息时的处理
  23. websocketOnMessage(e);
  24. };
  25. webSock.onclose = function (e) {
  26. // 连接关闭时的处理
  27. websocketClose(e);
  28. };
  29. // 连接发生错误的回调方法
  30. webSock.onerror = function () {
  31. websocketError();
  32. };
  33. }
  34. //心跳设置
  35. const heartCheck = {
  36. timeout: 30000, //每段时间发送一次心跳包 这里设置为20s
  37. timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
  38. start: function () {
  39. this.timeoutObj = setInterval(function () {
  40. if (connectState) webSock.send(JSON.stringify({ type: 0 }));
  41. }, this.timeout);
  42. },
  43. reset: function () {
  44. clearTimeout(this.timeoutObj);
  45. this.start();
  46. }
  47. };
  48. //定义重连函数
  49. const reConnect = () => {
  50. console.log('尝试重新连接');
  51. if (connectState) return; //如果已经连上就不在重连了
  52. rec && clearTimeout(rec);
  53. rec = setTimeout(function () {
  54. // 延迟5秒重连 避免过多次过频繁请求重连
  55. if (!connectState) {
  56. createWebSocket();
  57. }
  58. }, 5000);
  59. };
  60. // 实际调用的方法
  61. function sendSock(agentData) {
  62. if (webSock.readyState === webSock.OPEN) {
  63. // 若是ws开启状态
  64. webSock.send(agentData);
  65. } else if (webSock.readyState === webSock.CONNECTING) {
  66. // 若是 正在开启状态,则等待1s后重新调用
  67. setTimeout(function () {
  68. sendSock(agentData);
  69. }, 1000);
  70. } else {
  71. // 若未开启 ,则等待1s后重新调用
  72. setTimeout(function () {
  73. sendSock(agentData);
  74. }, 1000);
  75. }
  76. }
  77. function websocketClose() {
  78. connectState = false;
  79. webSock = null;
  80. global_callback = null;
  81. closeFlag = false;
  82. heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
  83. // 清除重连定时器
  84. rec && clearTimeout(rec);
  85. }
  86. // 数据接收
  87. function websocketOnMessage(msg) {
  88. if (!msg || !msg.data) {
  89. // 可能得情况 - 心跳机制、无关信息接收
  90. console.log('收到数据:空消息');
  91. return;
  92. }
  93. console.log(msg);
  94. // 收到信息为Blob类型时
  95. const result = JSON.parse(msg.data);
  96. if (result.type === 0 || result.type === '0') {
  97. //自己的业务
  98. } else {
  99. global_callback(result);
  100. }
  101. }
  102. function closeSock({ activeClose = false }) {
  103. closeFlag = activeClose;
  104. // 清除心跳定时器
  105. heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
  106. // 清除重连定时器
  107. rec && clearTimeout(rec);
  108. if (closeFlag) {
  109. // 关闭socket
  110. webSock.close();
  111. }
  112. // 初始化相关变量
  113. webSock = null;
  114. connectState = false;
  115. }
  116. const websocketError = () => {
  117. closeSock({ activeClose: true });
  118. // 执行重连
  119. reConnect();
  120. };
  121. function websocketOpen() {
  122. webSock.send('Authorization: Bearer ' + getToken());
  123. connectState = true;
  124. heartCheck.start(); //发送心跳 看个人项目需求
  125. }
  126. export { sendSock, createWebSocket, closeSock };