|
@@ -0,0 +1,91 @@
|
|
|
|
|
+class WebSocketService {
|
|
|
|
|
+ constructor() {
|
|
|
|
|
+ this.websocket = null;
|
|
|
|
|
+ this.heartbeatTimer = null;
|
|
|
|
|
+ this.reconnectTimer = null;
|
|
|
|
|
+ this.token = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ initWebSocket(token) {
|
|
|
|
|
+ if (!token) {
|
|
|
|
|
+ console.warn('❌ WebSocket token 为空');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.token = token;
|
|
|
|
|
+ const wsUrl = `${process.env.VUE_APP_WS_URL}/${token}`;
|
|
|
|
|
+ console.log("🔌 WebSocket连接中:", process.env.VUE_APP_WS_URL);
|
|
|
|
|
+ console.log("🔌 WebSocket连接中:", wsUrl);
|
|
|
|
|
+
|
|
|
|
|
+ this.websocket = new WebSocket(wsUrl);
|
|
|
|
|
+
|
|
|
|
|
+ this.websocket.onopen = this.websocketonopen.bind(this);
|
|
|
|
|
+ this.websocket.onerror = this.websocketonerror.bind(this);
|
|
|
|
|
+ this.websocket.onmessage = this.setOnmessageMessage.bind(this);
|
|
|
|
|
+ this.websocket.onclose = this.websocketclose.bind(this);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ websocketonopen() {
|
|
|
|
|
+ console.log('✅ WebSocket连接成功');
|
|
|
|
|
+ this.startHeartbeat();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ websocketonerror(e) {
|
|
|
|
|
+ console.error("❌ WebSocket连接错误:", e);
|
|
|
|
|
+ this.reconnect();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ websocketclose(e) {
|
|
|
|
|
+ console.warn("⚠️ WebSocket连接关闭:", e);
|
|
|
|
|
+ this.stopHeartbeat();
|
|
|
|
|
+ this.reconnect();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ reconnect() {
|
|
|
|
|
+ if (this.reconnectTimer) return;
|
|
|
|
|
+ this.reconnectTimer = setTimeout(() => {
|
|
|
|
|
+ console.warn('🔁 尝试重新连接 WebSocket...');
|
|
|
|
|
+ this.initWebSocket(this.token);
|
|
|
|
|
+ this.reconnectTimer = null;
|
|
|
|
|
+ }, 5000);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setOnmessageMessage(event) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const msg = JSON.parse(event.data);
|
|
|
|
|
+ console.log("📩 收到消息:", msg);
|
|
|
|
|
+ if (msg.type) {
|
|
|
|
|
+ window.dispatchEvent(new CustomEvent(msg.type, { detail: msg }));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error("WebSocket消息解析失败:", err);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ startHeartbeat() {
|
|
|
|
|
+ this.stopHeartbeat();
|
|
|
|
|
+ this.heartbeatTimer = setInterval(() => {
|
|
|
|
|
+ if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
|
|
|
|
|
+ this.websocket.send(JSON.stringify({ type: 'heartbeat', time: new Date().toISOString() }));
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 30000);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stopHeartbeat() {
|
|
|
|
|
+ if (this.heartbeatTimer) {
|
|
|
|
|
+ clearInterval(this.heartbeatTimer);
|
|
|
|
|
+ this.heartbeatTimer = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ destroy() {
|
|
|
|
|
+ this.stopHeartbeat();
|
|
|
|
|
+ if (this.websocket) {
|
|
|
|
|
+ this.websocket.close();
|
|
|
|
|
+ this.websocket = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ console.log("🧹 WebSocket 已销毁");
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default new WebSocketService();
|