useWebSocket.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // noinspection JSUnusedGlobalSymbols
  2. import { computed, reactive, ref, unref } from 'vue';
  3. import { useWebSocket as $useWebSocket, WebSocketResult } from '@vueuse/core';
  4. import { getToken } from '/@/utils/auth';
  5. const state = reactive({
  6. server: '',
  7. sendValue: '',
  8. recordList: [] as { id: number; time: number; res: string }[],
  9. });
  10. const result = ref<WebSocketResult<any>>();
  11. const listeners = new Map();
  12. /**
  13. * 开启 WebSocket 链接,全局只需执行一次
  14. * @param url
  15. */
  16. export function connectWebSocket(url: string) {
  17. if (!unref(getIsOpen)) {
  18. state.server = url;
  19. //update-begin-author:taoyan date:2022-4-24 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
  20. let token = (getToken() || '') as string;
  21. result.value = $useWebSocket(state.server, {
  22. // 自动重连
  23. autoReconnect: true,
  24. // 心跳检测
  25. heartbeat: false,
  26. protocols: [token],
  27. });
  28. //update-end-author:taoyan date:2022-4-24 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
  29. //【jeecgboot-vue3/issues/I5KULW】Websocket 连接后自动给关闭
  30. //result.value.open();
  31. const ws = unref(result.value.ws);
  32. if (ws) {
  33. ws.onopen = onOpen;
  34. ws.onclose = onClose;
  35. ws.onerror = onError;
  36. ws.onmessage = onMessage;
  37. }
  38. }
  39. }
  40. function onOpen() {
  41. console.log('[WebSocket] 连接成功');
  42. }
  43. function onClose(e) {
  44. console.log('[WebSocket] 连接断开:', e);
  45. }
  46. function onError(e) {
  47. console.log('[WebSocket] 连接发生错误: ', e);
  48. }
  49. function onMessage(e) {
  50. if (e.data === 'ping') {
  51. return;
  52. }
  53. console.debug('[WebSocket] -----接收消息-------', e.data);
  54. try {
  55. const data = JSON.parse(e.data);
  56. for (const callback of listeners.keys()) {
  57. try {
  58. callback(data);
  59. } catch (err) {
  60. console.error(err);
  61. }
  62. }
  63. } catch (err) {
  64. console.error('[WebSocket] data解析失败:', err);
  65. }
  66. }
  67. /**
  68. * 判断 WebSocket 是否是开启状态
  69. */
  70. export const getIsOpen = computed(() => result.value?.status.value === 'OPEN');
  71. /**
  72. * 添加 WebSocket 消息监听
  73. * @param callback
  74. */
  75. export function onWebSocket(callback: (data: object) => any) {
  76. if (!listeners.has(callback)) {
  77. if (typeof callback === 'function') {
  78. listeners.set(callback, null);
  79. } else {
  80. console.debug('[WebSocket] 添加 WebSocket 消息监听失败:传入的参数不是一个方法');
  81. }
  82. }
  83. }
  84. /**
  85. * 解除 WebSocket 消息监听
  86. *
  87. * @param callback
  88. */
  89. export function offWebSocket(callback: (data: object) => any) {
  90. listeners.delete(callback);
  91. }
  92. export function useWebSocket() {
  93. return unref(result);
  94. }