liming 1 viikko sitten
vanhempi
sitoutus
db735595a1
1 muutettua tiedostoa jossa 184 lisäystä ja 143 poistoa
  1. 184 143
      src/stores/modules/webSocketStore.js

+ 184 - 143
src/stores/modules/webSocketStore.js

@@ -1,184 +1,225 @@
 // src/stores/websocket.ts
 import { defineStore } from 'pinia'
-import { ref } from 'vue' 
 import { $root as protobuf } from '@/common/proto/proto'
 import * as Constant from '@/common/constant/Constant'
-import { useWalletStore } from "@/stores/modules/walletStore";
-
-//  MessageType = $root.lookupType("protocol.Message");
-
-
+import { useWalletStore } from "@/stores/modules/walletStore"
+
+export const useWebSocketStore = defineStore('webSocketStore', {
+  // 状态定义
+  state: () => ({
+    socket: null ,
+    peer: null,
+    lockConnection: false,
+    reconnectAttempts: 0,
+    maxReconnectAttempts: 5,
+    reconnectInterval: 3000,
+    messages: [] ,
+    unreadMessages: []  ,
+    lastMessage: null ,
+    
+    // 心跳检测配置
+    heartCheck: {
+      timeout: 10000,
+      timeoutObj: null  ,
+      serverTimeoutObj: null,
+      num: 3
+    }
+  }),
 
-export const useWebSocketStore = defineStore('webSocketStore', () => {
-  const socket = ref(null) // 创建WebSocket对象
-  const peer = ref(null) // 创建RTCPeerConnection对象
-  const lockConnection = ref(false)
-  const reconnectAttempts = ref(0)
-  const maxReconnectAttempts = 5
-  const reconnectInterval = 3000
+  // 计算属性
+  getters: {
+    isConnected: (state) => state.socket?.readyState === WebSocket.OPEN,
+    hasUnreadMessages: (state) => state.unreadMessages.length > 0
+  },
 
-  // 心跳检测
-  const heartCheck = {
-    timeout: 10000,
-    timeoutObj: null,
-    serverTimeoutObj: null,
-    num: 3,
-    start: function () {
+  // 方法
+  actions: {
+    startHeartbeat() {
       const self = this
-      const _num = this.num
+      const _num = this.heartCheck.num
       
-      this.timeoutObj && clearTimeout(this.timeoutObj)
-      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
+      this.heartCheck.timeoutObj && clearTimeout(this.heartCheck.timeoutObj)
+      this.heartCheck.serverTimeoutObj && clearTimeout(this.heartCheck.serverTimeoutObj)
       
-      this.timeoutObj = setTimeout(() => {
-        if (socket.value?.readyState === 1) {
+      this.heartCheck.timeoutObj = setTimeout(() => {
+        if (this.socket?.readyState === WebSocket.OPEN) {
           const data = {
             type: "heatbeat",
             content: "ping",
           }
-          const message = protobuf.lookup("protocol.Message")
-          const messagePB = message.create(data)
-          socket.value.send(message.encode(messagePB).finish())
+          const MessageType = protobuf.lookupType("protocol.Message")
+          const messagePB = MessageType.create(data)
+          const buffer = MessageType.encode(messagePB).finish()
+          this.socket.send(buffer)
         }
 
-        self.serverTimeoutObj = setTimeout(() => {
+        self.heartCheck.serverTimeoutObj = setTimeout(() => {
           _num--
           if (_num <= 0) {
             console.log("the ping num is more then 3, close socket!")
-            socket.value?.close()
+            this.socket?.close()
           }
-        }, self.timeout)
-      }, this.timeout)
-    }
-  }
-
-  // 连接WebSocket
-  const connect = (userUuid) => {
-    console.log("开始连接...")
-    peer.value = new RTCPeerConnection()
-    socket.value = new WebSocket(`ws://192.168.0.59:8888/api/v1/socket.io?user=${userUuid}`)
+        }, self.heartCheck.timeout)
+      }, this.heartCheck.timeout)
+    },
+
+    resetHeartbeat() {
+      this.heartCheck.timeoutObj && clearTimeout(this.heartCheck.timeoutObj)
+      this.heartCheck.serverTimeoutObj && clearTimeout(this.heartCheck.serverTimeoutObj)
+      this.heartCheck.num = 3
+    },
+
+    connect(userUuid) {
+      console.log("开始连接...")
+      this.disconnect() // 确保先断开现有连接
+      
+      this.peer = new RTCPeerConnection()
+      this.socket = new WebSocket(`ws://192.168.0.59:8888/api/v1/socket.io?user=${userUuid}`)
 
-    socket.value.onopen = () => {
-      heartCheck.start()
-      console.log("链接")
-      webrtcConnection()
-    }
+      this.socket.onopen = () => {
+        this.startHeartbeat()
+        console.log("WebSocket连接成功")
+        this.webrtcConnection()
+      }
 
-    socket.value.onmessage = (event) => {
-      heartCheck.start()
-      handleMessage(event.data)
-    }
+      this.socket.onmessage = (event) => {
+        this.startHeartbeat()
+        this.handleMessage(event.data)
+      }
 
-    socket.value.onclose = () => {
-      console.log("关闭并重新连接-->--->")
-      reconnect()
-    }
+      this.socket.onclose = () => {
+        console.log("连接关闭,尝试重新连接...")
+        this.resetHeartbeat()
+        this.reconnect()
+      }
 
-    socket.value.onerror = () => {
-      console.log("error----->>>>")
-      reconnect()
-    }
-  }
+      this.socket.onerror = (error) => {
+        console.error("WebSocket错误:", error)
+        this.resetHeartbeat()
+        this.reconnect()
+      }
+    },
 
-  // 处理接收到的消息
-  const handleMessage = (data) => {
-    const messageProto = protobuf.lookupType("protocol.Message")
-    const reader = new FileReader()
-    
-    reader.readAsArrayBuffer(data)
-    reader.onload = (event) => {
-      const messagePB = messageProto.decode(new Uint8Array(event.target?.result))
-      // 单独解码 
-      console.log(messagePB)
+    handleMessage(data) {
+      const MessageType = protobuf.lookupType("protocol.Message")
+      const reader = new FileReader()
       
-      if (messagePB.type === "heatbeat") return
-      
-      if (messagePB.type === Constant.MESSAGE_TRANS_TYPE) {
-        dealWebRtcMessage(messagePB)
-        return
+      reader.onload = (event) => {
+        try {
+          const messagePB = MessageType.decode(new Uint8Array(event.target?.result))
+          const message = MessageType.toObject(messagePB, {
+            longs: String,
+            enums: String,
+            bytes: String,
+          })
+          
+          console.log("收到消息:", message)
+          
+          // 更新状态
+          this.messages.push(message)
+          this.lastMessage = message
+          
+          if (message.type === "heatbeat") return
+          
+          if (message.type === Constant.MESSAGE_TRANS_TYPE) {
+            this.dealWebRtcMessage(message)
+            return
+          }
+          
+          // 其他消息处理逻辑...
+          
+        } catch (error) {
+          console.error("消息解码错误:", error)
+        }
       }
       
-      // 其他消息处理...
-    }
-  }
+      reader.readAsArrayBuffer(data)
+    },
 
-  // WebRTC 连接
-  const webrtcConnection = () => {
-    if (!peer.value) return
-    
-    peer.value.onicecandidate = (e) => {
-      if (e.candidate && socket.value) {
-        const candidate = {
-          type: 'answer_ice',
-          iceCandidate: e.candidate
+    webrtcConnection() {
+      if (!this.peer) return
+      
+      this.peer.onicecandidate = (e) => {
+        if (e.candidate && this.socket) {
+          const candidate = {
+            type: 'answer_ice',
+            iceCandidate: e.candidate
+          }
+          const message = {
+            content: JSON.stringify(candidate),
+            type: Constant.MESSAGE_TRANS_TYPE,
+          }
+          this.sendMessage(message)
         }
-        const message = {
-          content: JSON.stringify(candidate),
-          type: Constant.MESSAGE_TRANS_TYPE,
+      }
+
+      this.peer.ontrack = (e) => {
+        if (e && e.streams) {
+          const remoteVideo = document.getElementById("remoteVideoReceiver")
+          const remoteAudio = document.getElementById("audioPhone")
+          
+          if (remoteVideo) remoteVideo.srcObject = e.streams[0]
+          if (remoteAudio) remoteAudio.srcObject = e.streams[0]
         }
-        sendMessage(message)
       }
-    }
+    },
 
-    peer.value.ontrack = (e) => {
-      if (e && e.streams) {
-        const remoteVideo = document.getElementById("remoteVideoReceiver")
-        const remoteAudio = document.getElementById("audioPhone")
-        
-        if (remoteVideo) remoteVideo.srcObject = e.streams[0]
-        if (remoteAudio) remoteAudio.srcObject = e.streams[0]
+    reconnect() {
+      if (this.lockConnection || this.reconnectAttempts >= this.maxReconnectAttempts) {
+        return
       }
-    }
-  }
 
-  // 处理WebRTC消息
-  const dealWebRtcMessage = (messagePB) => {
-    // 实现与React版本相同的逻辑
-  }
+      this.lockConnection = true
+      this.reconnectAttempts++
+      
+      console.log(`重新连接中... (尝试 ${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
+      
+      setTimeout(() => {
+        this.connect(localStorage.uuid)
+        this.lockConnection = false
+      }, this.reconnectInterval)
+    },
+
+    disconnect() {
+      if (this.socket) {
+        this.resetHeartbeat()
+        this.socket.close()
+        this.socket = null
+      }
+      if (this.peer) {
+        this.peer.close()
+        this.peer = null
+      }
+      this.reconnectAttempts = 0
+    },
 
-  // 重新连接
-  const reconnect = () => {
-    if (lockConnection.value) return
-    lockConnection.value = true
+    sendMessage(messageData) {
+      if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
+        console.error("WebSocket未连接")
+        return false
+      }
 
-    setTimeout(() => {
-      if (socket.value?.readyState !== 1) {
-        connect(localStorage.uuid)
+      const walletStore = useWalletStore()
+      const data = {
+        ...messageData,
+        fromUsername: walletStore.username,
+        from: walletStore.account,
       }
-      lockConnection.value = false
-    }, 10000)
-  }
+      
+      try {
+        const MessageType = protobuf.lookupType("protocol.Message")
+        const messagePB = MessageType.create(data)
+        const buffer = MessageType.encode(messagePB).finish()
+        this.socket.send(buffer)
+        return true
+      } catch (error) {
+        console.error("消息编码错误:", error)
+        return false
+      }
+    },
 
-  // 发送消息
-  const sendMessage = (messageData) => {
-    if (!socket.value) return
-    const walletStore = useWalletStore()
-    const data = {
-      ...messageData,
-      fromUsername: walletStore.username,
-      from: walletStore.account,
+    dealWebRtcMessage(message) {
+      // 实现WebRTC消息处理逻辑
     }
-    
-    const message = protobuf.lookup("protocol.Message")
-    const messagePB = message.create(data)
-    socket.value.send(message.encode(messagePB).finish())
-  }
-
-  // 关闭连接
-  const close = () => {
-    socket.value?.close()
-    peer.value?.close()
-    socket.value = null
-    peer.value = null
-  }
-
-  return {
-    socket,
-    peer,
-    connect,
-    sendMessage,
-    close,
-    dealWebRtcMessage,
-    webrtcConnection
   }
 })