fix: update dependences

This commit is contained in:
merlin
2026-03-02 15:51:33 +08:00
parent b40691a4a3
commit 6f205d2408
7 changed files with 1245 additions and 2029 deletions

2818
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,9 +10,9 @@
"proxy": "node proxy.js"
},
"dependencies": {
"axios": "^1.12.0",
"axios": "^1.13.6",
"crypto-js": "^4.2.0",
"dplayer": "^1.27.0",
"dplayer": "^1.27.1",
"element-plus": "^2.9.4",
"express": "^4.21.2",
"hls.js": "^1.5.20",

View File

@@ -1,186 +0,0 @@
import { defineStore } from "pinia";
import {
saveMessages,
loadMessages,
deleteMessages,
} from "@/functions/historyMessages";
import {
saveGroupMessages,
loadGroupMessages,
deleteGroupMessages,
} from "@/functions/groupHistoryMessage";
import { toRaw } from "vue";
export const messageStore = defineStore("messageStore", {
// 定义一个响应式数组来存储聊天消息
state: () => ({
historymessages: [],
messages: [],
sender: "", //选择的聊天用户id
target: "", //用户自己的id
corresponding: [],
}),
// 定义操作消息的函数
actions: {
// 添加消息到数组
addMessage(message) {
this.messages.push(message);
},
// 清空所有消息
clearMessages() {
this.messages = [];
},
setCorresponding() {
// 过滤出当前聊天中的消息
this.corresponding = this.messages.filter(
(msg) =>
(msg.sender === this.sender && msg.target === this.target) ||
(msg.sender === this.target && msg.target === this.sender)
);
const historymessages = this.historymessages.filter(
(msg) =>
(msg.sender === this.sender && msg.target === this.target) ||
(msg.sender === this.target && msg.target === this.sender)
);
this.corresponding = [...historymessages, ...this.corresponding];
},
// 清楚当前登录的聊天数据,保存到本地
async saveMessagesHistory(id) {
const messages = toRaw(this.messages);
await saveMessages(id, messages);
},
// 加载本地聊天数据
async loadMessagesHistory(u_id) {
try {
this.historymessages = await loadMessages(u_id);
// 确保历史消息是数组类型
if (!Array.isArray(this.historymessages)) {
console.error("历史消息数据无效:", this.historymessages);
this.historymessages = []; // 如果数据无效,设置为空数组
}
} catch (error) {
console.log("加载历史消息时出错" + error);
}
},
async deleteMessagesHistory(u_id, f_id) {
this.historymessages = this.historymessages.filter(
(msg) =>
!(
(msg.sender === f_id && msg.target === u_id) ||
(msg.sender === u_id && msg.target === f_id)
)
);
this.messages = this.messages.filter(
(msg) =>
!(
(msg.sender === f_id && msg.target === u_id) ||
(msg.sender === u_id && msg.target === f_id)
)
);
if (f_id === this.sender) {
console.log("清除对应聊天数据展示栈");
this.corresponding = [];
}
const messages = JSON.parse(JSON.stringify(toRaw(this.historymessages)));
try {
await deleteMessages(u_id, messages);
} catch (error) {
console.log("删除历史消息时出错" + error);
}
},
},
// 定义计算属性(可选)
getters: {
// 获取消息数量
messageCount: (state) => state.messages.length,
},
});
export const messageSignStore = defineStore("messageSignStore", {
state: () => ({
sign: [],
}),
actions: {
addSign(sign) {
// 检查是否已经存在相同的值
const exists = this.sign.some(
(item) =>
item.sender === sign.sender && item.sender_name === sign.sender_name
);
if (!exists) {
this.sign.push(sign);
} else {
console.warn(`Sign "${sign}" already exists and will not be added.`);
}
},
clearSign() {
this.sign = [];
},
removeSign(sign) {
// 找到相同值的索引
const index = this.sign.indexOf(sign);
if (index !== -1) {
// 如果存在,删除该值
this.sign.splice(index, 1);
} else {
console.warn(`Sign "${sign}" not found.`);
}
},
},
});
export const groupMessageStore = defineStore("groupMessageStore", {
state: () => ({
g_id: "",
historymessages: [],
messages: [],
corresponding: [],
}),
actions: {
addMessage(message) {
this.messages.push(message);
},
clearMessages() {
this.messages = [];
},
async initMessages() {
this.historymessages = [...this.historymessages, ...this.messages];
this.messages = [];
},
async getHistoryMessages(u_id, g_id) {
this.g_id = g_id;
const key = `${u_id}-${g_id}`;
try {
this.historymessages = await loadGroupMessages(key);
console.log("缓存到历史消息:");
console.log(this.historymessages);
// 确保历史消息是数组类型
if (!Array.isArray(this.historymessages)) {
console.error("历史消息数据无效:", this.historymessages);
this.historymessages = []; // 如果数据无效,设置为空数组
}
} catch (error) {
console.log("加载历史消息时出错" + error);
}
},
async saveMessagesHistory(u_id, g_id) {
const key = `${u_id}-${g_id}`;
console.log(key);
const messages = toRaw(this.messages);
this.messages = [];
this.historymessages = [];
await saveGroupMessages(key, messages);
},
async deleteMessagesHistory(u_id, g_id) {
const key = `${u_id}-${g_id}`;
this.historymessages = [];
this.messages = [];
await deleteGroupMessages(key, []);
},
},
});

View File

@@ -1,5 +1,6 @@
import { ref } from "vue";
import { defineStore } from "pinia";
import { connectWebSocket, disconnectWebSocket, sendMessage, setIsManualClose } from '@/websocket/roomSocket'
interface PlayroomState {
id: number
@@ -20,6 +21,14 @@ export const PlayroomStore = defineStore("PlayroomStore",
currentPlayroom.value = playroom;
}
const getCurrentPlayroom = () =>{
return currentPlayroom.value;
}
const getCurrentId = () =>{
return currentPlayroom.value?.r_id;
}
const setCurrentUrl = (url: string) => {
currentUrl.value = url;
}
@@ -30,9 +39,35 @@ export const PlayroomStore = defineStore("PlayroomStore",
}
return {
currentPlayroom,
getCurrentPlayroom,
getCurrentId,
setCurrentPlayroom,
setCurrentUrl,
clearPlayroom,
}
})
})
export const videoSocketStore = defineStore("videoSocketStore",{
state: () => ({
isConnected: false,
hasGotMessage: false,
id: 0
}),
actions: {
connect(id: number) {
this.id = id;
if (this.isConnected === true) return
connectWebSocket();
this.isConnected = true;
},
disconnect() {
setIsManualClose(true);
disconnectWebSocket();
this.isConnected = false;
},
send(message: string) {
sendMessage(JSON.stringify(message));
}
}
})

View File

@@ -99,58 +99,38 @@ export const connectWebSocket = () => {
// TODO: 需要使用groupId进行消息标记
break;
case "VIDEO_SYNC":
console.log("视频同步消息", MessageData);
break;
// 语音通话相关:
case "VOICE_CALL_REQUEST":
ElMessage.info("您有一个新的语音通话请求");
break;
case "VOICE_CALL_RESPONSE":
console.log("收到语音通话响应消息");
break;
case "VOICE_CALL_DENY":
ElMessage.info("对方拒绝了您的语音通话请求");
break;
case "VOICE_CALL_END":
ElMessage.info("语音通话已结束");
break;
case "VOICE_ICE_CANDIDATE":
console.log("收到新的ICE候选", MessageData.candidate);
break;
case "VOICE_SDP_OFFER":
console.log("收到SDP Offer", MessageData.sdp);
break;
case "VOICE_SDP_ANSWER":
console.log("收到SDP Answer", MessageData.sdp);
break;
}
}catch(error){
console.error("解析 JSON 失败:", error);
}
// try {
// const MessageData = JSON.parse(event.data);
// //是否为上下线消息(三类消息)
// if (!MessageData.system) {
// //是否为新消息
// if (MessageData.message) {
// messagePoint.hasNewMessage = true;
// if (MessageData.group) {
// //四类消息,群聊消息
// console.log("有新群消息");
// groupMessage.addMessage(MessageData);
// console.log(groupMessage.messages);
// messageSign.addSign({
// sender_name: MessageData.sender_name,
// g_id: MessageData.g_id,
// g_name: MessageData.g_name,
// });
// } else {
// //一类消息,私聊消息
// console.log("有新消息");
// message.addMessage(MessageData);
// console.log(message.messages);
// messageSign.addSign({
// sender: MessageData.sender,
// sender_name: MessageData.sender_name,
// });
// }
// }
// } else {
// if (MessageData.engaged) {
// // 五类消息,账号重复登录逻辑
// setIsManualClose(true);
// disconnectWebSocket();
// ElMessage("账号重复登录,请注意密码泄露");
// console.log("账号重复登陆");
// window.location.replace("/");
// } else {
// //三类消息,指示用户上下线
// if (MessageData.status === "online")
// ElMessage("用户:" + MessageData.u_name + "上线");
// else {
// ElMessage("用户:" + MessageData.u_name + "下线");
// }
// }
// }
// } catch (error) {
// console.error("解析 JSON 失败:", error);
// }
};
socket.value.onerror = (error) => {

View File

@@ -0,0 +1,149 @@
import { ref } from "vue";
import { userInfoStore } from "@/store/user";
import { ElMessage } from "element-plus";
import { PlayroomStore } from "@/store/playroom";
// userinfo 实例
const userinfo = userInfoStore();
// 延迟获取 playroom 实例,避免循环依赖
const getPlayroom = () => {
return PlayroomStore();
};
// WebSocket 实例
const socket = ref(null);
const isManualClose = ref(false);
const reconnectScheduled = ref(false);
const retryCount = ref(0);
export const getRetryCount = () => {
return retryCount.value;
};
export const addRetryCount = () => {
retryCount.value = retryCount.value + 1;
};
export const resetRetryCount = () => {
retryCount.value = 0;
};
export const setReconnectScheduled = (value) => {
reconnectScheduled.value = value;
};
export const getReconnectScheduled = () => {
return reconnectScheduled.value;
};
export const setIsManualClose = (value) => {
isManualClose.value = value;
};
export const getIsManualClose = () => {
return isManualClose.value;
};
// 连接WebSocket
export const connectWebSocket = () => {
const playroom = getPlayroom();
const protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
const host = window.location.host;
const socketUrl = `${protocol}${host}/ws/video?r_id=${playroom.getCurrentId()}`;
// const socketUrl = `ws://localhost:8080/online?u_id=${userinfo.user.u_id}&u_name=${userinfo.user.u_name}`;
if (socket.value && socket.value.readyState !== WebSocket.CLOSED) {
console.log("还在重连中...");
return;
}
const retrytime = getRetryCount();
if (retrytime >= 10) {
console.log("重连失败,请稍后再试");
return;
}
console.log(retrytime);
socket.value = new WebSocket(socketUrl, "token-"+ userinfo.token);
socket.value.onopen = (event) => {
console.log("WebSocket for video 连接已建立", event);
setReconnectScheduled(false);
setIsManualClose(false);
resetRetryCount();
};
//处理消息逻辑
socket.value.onmessage = (event) => {
console.log("从服务器收到消息:", event.data);
try{
const MessageData = JSON.parse(event.data);
const cmd = MessageData.cmd;
switch(cmd){
case "VIDEO_SYNC":
console.log("视频同步消息", MessageData);
break;
}
}catch(error){
console.error("解析 JSON 失败:", error);
}
};
socket.value.onerror = (error) => {
console.error("WebSocket for video 发生错误:", error);
// console.log(error);
setReconnectScheduled(true);
socket.value.close();
};
socket.value.onclose = (event) => {
if (!getIsManualClose()) {
if (getReconnectScheduled()) {
socket.value = null;
addRetryCount();
setTimeout(reConnectWebSocket, 5000);
setReconnectScheduled(false);
} else {
// console.log("websocket因为浏览器省电设置断开");
console.log("WebSocket for video 连接已关闭", event);
}
}
};
};
// 断开WebSocket连接
export const disconnectWebSocket = () => {
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
socket.value.close();
}
};
// 重连机制
export const reConnectWebSocket = () => {
connectWebSocket();
};
// 发送消息
export const sendMessage = (message) => {
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
socket.value.send(message);
} else {
console.warn("WebSocket for video 未连接,无法发送消息");
}
};
//没有错误的重连,只是浏览器在后台断开了连接
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
} else {
if (!getIsManualClose() && socket.value.readyState === WebSocket.CLOSED) {
if (getReconnectScheduled()) {
return;
}
reConnectWebSocket();
}
}
});

View File

@@ -32,6 +32,8 @@ export default defineConfig({
// ws: true,
// }
},
host: '0.0.0.0',
port: 5173,
},
// server: {
// https:{