123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // 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'
- // MessageType = $root.lookupType("protocol.Message");
- 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
- // 心跳检测
- const heartCheck = {
- timeout: 10000,
- timeoutObj: null,
- serverTimeoutObj: null,
- num: 3,
- start: function () {
- const self = this
- const _num = this.num
-
- this.timeoutObj && clearTimeout(this.timeoutObj)
- this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
-
- this.timeoutObj = setTimeout(() => {
- if (socket.value?.readyState === 1) {
- const data = {
- type: "heatbeat",
- content: "ping",
- }
- const message = protobuf.lookup("protocol.Message")
- const messagePB = message.create(data)
- socket.value.send(message.encode(messagePB).finish())
- }
- self.serverTimeoutObj = setTimeout(() => {
- _num--
- if (_num <= 0) {
- console.log("the ping num is more then 3, close socket!")
- socket.value?.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}`)
- socket.value.onopen = () => {
- heartCheck.start()
- console.log("链接")
- webrtcConnection()
- }
- socket.value.onmessage = (event) => {
- heartCheck.start()
- handleMessage(event.data)
- }
- socket.value.onclose = () => {
- console.log("关闭并重新连接-->--->")
- reconnect()
- }
- socket.value.onerror = () => {
- console.log("error----->>>>")
- 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)
-
- if (messagePB.type === "heatbeat") return
-
- if (messagePB.type === Constant.MESSAGE_TRANS_TYPE) {
- dealWebRtcMessage(messagePB)
- return
- }
-
- // 其他消息处理...
- }
- }
- // WebRTC 连接
- const webrtcConnection = () => {
- if (!peer.value) return
-
- peer.value.onicecandidate = (e) => {
- if (e.candidate && socket.value) {
- const candidate = {
- type: 'answer_ice',
- iceCandidate: e.candidate
- }
- const message = {
- content: JSON.stringify(candidate),
- type: Constant.MESSAGE_TRANS_TYPE,
- }
- 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]
- }
- }
- }
- // 处理WebRTC消息
- const dealWebRtcMessage = (messagePB) => {
- // 实现与React版本相同的逻辑
- }
- // 重新连接
- const reconnect = () => {
- if (lockConnection.value) return
- lockConnection.value = true
- setTimeout(() => {
- if (socket.value?.readyState !== 1) {
- connect(localStorage.uuid)
- }
- lockConnection.value = false
- }, 10000)
- }
- // 发送消息
- const sendMessage = (messageData) => {
- if (!socket.value) return
-
- const data = {
- ...messageData,
- fromUsername: localStorage.username,
- from: localStorage.uuid,
- }
-
- 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
- }
- })
|