he wei
2025-04-03 c6a2d2debf161b987ff91c6ac9560d10fc98c54b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// useWebSocket.js
import {
  ref,
  reactive,
  onMounted,
  onUnmounted,
  onActivated,
  onDeactivated,
} from "vue";
import getWsUrl from "@/utils/getWsUrl";
 
export default function (url) {
  url = getWsUrl(url);
  // 重连时间间隔 默认5秒
  const reConnectDelay = 5 * 1000;
 
  const socket = ref(null);
  const isConnected = ref(false);
  const message = ref("");
  let timer = null;
 
  const sendCallback = reactive([]);
 
  const connect = () => {
    if (socket.value) {
      socket.value.close();
    }
    socket.value = new WebSocket(url);
 
    socket.value.onopen = () => {
      isConnected.value = true;
      console.log("WebSocket Connected, url: ", url);
      sendCallback.forEach((v) => v());
      sendCallback.length = 0;
    };
 
    socket.value.onmessage = (event) => {
      // 处理接收到的消息
      // console.log("Received:", event.data);
      // 可以在这里通过 emit 发送消息到组件
      message.value = event.data;
    };
 
    socket.value.onerror = (Event) => {
      console.error("WebSocket Error:", Event, url);
      WSClose(Event);
    };
 
    socket.value.onclose = WSClose;
    
  };
 
  // 发送数据
  const sendData = (data) => {
    if (socket.value && socket.value.readyState === socket.value.OPEN) {
      // console.log('send', data, '=============');
      socket.value.send(data);
    } else {
      sendCallback.push(() => sendData(data));
    }
  };
  
  function WSClose(Event) {
    isConnected.value = false;
    if (socket.value) {
      switch (socket.value.readyState) {
        case 0:
          socket.value.onopen = () => {
            socket.value.close();
            console.log('链接关闭', url, 'close事件对象:', Event);
            socket.value = null;
            // 没有event对象 则为手动关闭
            if (Event) {
              reConnect();
            }
          }
          break;
        case 1:
          socket.value.close();
          console.log('链接关闭', url, 'close事件对象:', Event);
          socket.value = null;
          // 没有event对象 则为手动关闭
          if (Event) {
            reConnect();
          }
          break;
        case 2:
          socket.value.onclose = () => {
            console.log('链接关闭', url, 'close事件对象:', Event);
            socket.value = null;
            // 没有event对象 则为手动关闭
            if (Event) {
              reConnect();
            }
          }
          break;
        case 3:
          console.log('链接关闭', url, 'close事件对象:', Event);
          socket.value = null;
          // 没有event对象 则为手动关闭
          if (Event) {
            reConnect();
          }
          break;
      }
    }
  }
 
  // 重连
  function reConnect() {
    if (timer) {
      return false;
    }
    timer = setTimeout(() => {
      timer = null;
      connect();
    }, reConnectDelay);
  }
 
  onMounted(() => {
    // console.log('socket mount', Date.now(), '=============');
    console.log("on socket mount", url, "=============");
 
    connect();
  });
 
  onActivated(() => {
    if (!socket.value) {
      console.log("on socket active", url, "=============");
      connect();
    }
  });
 
  onDeactivated(() => {
    if (socket.value) {
      WSClose();
    }
  });
 
  onUnmounted(() => {
    if (socket.value) {
      WSClose();
    }
  });
 
  // 返回 socket 对象和状态
  return { socket, isConnected, message, sendData };
}