websocket.ts 3.5 KB

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