Files
phone-app------test1-/stores/friend-socket.js
2026-06-02 10:42:33 +08:00

255 lines
5.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
defineStore
} from "pinia";
import {
computed,
ref
} from "vue";
import {
friendSocketManager
} from '@/utils/friend-socket.js'
import {
getToken,
getUserId
} from "../utils/user-info";
export const useFriendSocketStore = defineStore('friendSocket', () => {
// ==================== 状态定义 ====================
const connectionStatus = ref('disconnected') //connecting | connected | disconnected | error
const messages = ref([])
const messageString = ref('')
const config = ref({
token: '',
UserId: ''
})
const taskCallId = ref('')
const command = ref(null)
const groupId = ref(null)
// 收到消息
const MessageReceived = ref(false)
// 日志数组和最大值
const logs = ref([])
const maxLogCount = ref(20)
// ==================== 计算属性 ====================
const isConnected = computed(() => connectionStatus.value === 'connected')
const isConnecting = computed(() => connectionStatus.value === 'connecting')
const isDisconnected = computed(() => connectionStatus.value === 'disconnected')
const isError = computed(() => connectionStatus.value === 'error')
const lastMessage = computed(() => messages.value[messages.value.length - 1])
// 日志方法
function addLog(type, connect) {
const now = new Date()
const time =
`${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`
logs.value.push({
type,
connect,
time
})
if (logs.value.length > maxLogCount.value) {
logs.value = logs.value.slice(-maxLogCount.value)
}
console.log(`[${type.toUpperCase()}] ${connect}`);
}
function clearLogs() {
logs.value = []
}
// ==================== 连接相关方法 ====================
function connect(options = {}) {
messages.value = []
messageString.value = ''
config.value = {
...config.value,
...options
}
addLog('info',
`准备连接FriendsWebSocket。Token:${config.value.token || '未设置'}。UserId: ${config.value.UserId || '未设置'}`
)
if (!config.value.token || !config.value.UserId) {
addLog('error', 'Token和UserId都不能为空')
return
}
connectionStatus.value = 'connecting'
friendSocketManager.connect({
token: config.value.token,
UserId: config.value.UserId,
onMessage: handleMessage,
onError: handleError,
onOpen: handleOpen,
onClose: handleClose,
onReconnect: handleReconnecting
})
setConnectionTimeout()
}
function disconnect() {
friendSocketManager.close()
connectionStatus.value = 'disconnected'
addLog('warn', '已主动断开连接')
}
async function send(message) {
if (!isConnected.value) {
addLog('error', '发送失败: 连接未建立')
throw new Error('连接未建立')
}
try {
await friendSocketManager.send(message)
addLog('send', typeof message === 'string' ? message : JSON.stringify(message))
return true
} catch (error) {
addLog('error', `发送失败: ${error.message || error}`)
throw error
}
}
// =====================连接成功发送验证标识指令为7===============
async function sendAuthData() {
const userId = getUserId()
const authData = {
"version": "1.1",
"body": {
"command": 7,
"sender": userId,
"avatar": "",
"sessionId": "",
"message": "",
"callBackMessage": false,
}
}
try {
await friendSocketManager.send(authData)
addLog('send', typeof authData === 'string' ? authData : JSON.stringify(authData))
return true
} catch (error) {
addLog('error', `发送验证失败: ${error.message || error}`)
throw error
}
}
// ==================== 事件回调 ====================
function handleOpen() {
connectionStatus.value = 'connected'
addLog('success', '连接成功!')
sendAuthData()
}
function handleClose() {
if (connectionStatus.value !== 'disconnected') {
// disconnect()
connectionStatus.value = 'disconnected'
addLog('warn', '连接已断开')
}
}
function handleError(error) {
addLog('error', `Socket错误: ${JSON.stringify(error)}`)
connectionStatus.value = 'error'
}
function handleReconnecting(attempts) {
connectionStatus.value = 'connecting'
addLog('warn', `重连中... (${attempts}/5)`)
}
function setConnectionTimeout() {
const timer = setTimeout(() => {
if (connectionStatus.value === 'connecting') {
connectionStatus.value = 'error'
addLog('error', '连接超时(10s)')
}
}, 10000)
// 返回 timer 以便必要时清除,但目前用不到
return timer
}
function handleMessage(messageData) {
addLog('receive', `收到: ${JSON.stringify(messageData)}`)
const msgBody = messageData.body || messageData;
// command 和 groupId和响应式变量重名冲突直接解构时重命名
const {
callBackMessage,
groupName,
command: msgCommand,
groupId: msgGroupId
} = msgBody || {}
switch (msgCommand) {
case 3:
command.value = msgCommand
groupId.value = msgGroupId
break
case 7:
command.value = msgCommand
break
case 1:
console.log("有好友消息");
MessageReceived.value = true
break
case 9:
console.log("群消息发送成功/有新群消息");
MessageReceived.value = true
break
default:
addLog('info', `未知事件类型`)
}
}
// ==================== 状态查询 ====================
function getStatusText() {
const statusMap = {
connecting: '连接中',
connected: '已连接',
disconnected: '未连接',
error: '连接错误'
}
return statusMap[connectionStatus.value] || '未知状态'
}
function getReadyState() {
return friendSocketManager.getReadyState()
}
// ==================== 导出 ====================
return {
// 状态
connectionStatus,
//属性变量
messageString,
logs,
config,
command,
groupId,
MessageReceived,
// 计算属性
isConnected,
isConnecting,
isDisconnected,
isError,
lastMessage,
// 方法
connect,
disconnect,
send,
addLog,
clearLogs,
getStatusText
}
})