Files
xk-admin/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts

193 lines
5.1 KiB
TypeScript
Raw Normal View History

2025-07-19 16:47:52 +08:00
import { onMounted, onUnmounted, ref } from 'vue';
import { useChatStore } from '../stores/chat';
import { useUserStore } from '../stores/user';
// useVbenUserStore
export function useWebSocket() {
const userStore = useUserStore();
const chatStore = useChatStore();
const socket = ref();
const isConnected = ref(false);
const isConnecting = ref(false);
const reconnectAttempts = ref(0);
const maxReconnectAttempts = 5;
const reconnectDelay = ref(1000);
const connectWebSocket = () => {
if (isConnecting.value || isConnected.value) return;
isConnecting.value = true;
chatStore.connectionStatus = 'connecting';
try {
// const wsUrl = import.meta.env.VITE_WS_URL || "wss://g-ws.nailaoyun.cn/ws"
2025-12-24 16:05:21 +08:00
// const wsUrl = import.meta.env.VITE_WS_URL || 'ws://localhost:12080/ws';
const wsUrl = 'wss://api.ws.g.xiaokang88.com/ws';
2025-07-19 16:47:52 +08:00
// const wsUrl = import.meta.env.VITE_WS_URL || "wss://g-ws.nailaoyun.cn/ws"
socket.value = new WebSocket(wsUrl);
socket.value.addEventListener('open', handleOpen);
socket.value.onmessage = handleMessage;
socket.value.addEventListener('close', handleClose);
socket.value.onerror = handleError;
} catch (error) {
console.error('WebSocket连接失败:', error);
isConnecting.value = false;
chatStore.connectionStatus = 'disconnected';
}
};
const handleOpen = (event) => {
console.log('WebSocket连接已建立');
isConnected.value = true;
isConnecting.value = false;
reconnectAttempts.value = 0;
reconnectDelay.value = 1000;
chatStore.connectionStatus = 'connected';
chatStore.socket = socket.value;
console.log(userStore.currentUser, 'ssssssssss')
// 绑定当前用户
2025-07-22 16:55:09 +08:00
if (userStore.currentUser?.doctor_id) {
bindUser(userStore.currentUser.doctor_id);
2025-07-19 16:47:52 +08:00
}
};
const handleMessage = (event) => {
try {
const data = JSON.parse(event.data);
console.log('收到WebSocket消息:', data);
// 优先处理通话信令(无论是否在当前聊天窗口)
if (data.call_id && data.call_status) {
handleCallSignal(data);
return;
}
// 处理普通消息 - 添加来源判断防止循环
if (data.sender_user_id && data.receiver_user_id) {
2025-07-22 16:55:09 +08:00
chatStore.handleIncomingMessage(data, userStore.currentUser?.doctor_id);
2025-07-19 16:47:52 +08:00
}
} catch (error) {
console.error('解析WebSocket消息失败:', error);
}
};
const handleClose = (event) => {
console.log('WebSocket连接已关闭:', event.code, event.reason);
isConnected.value = false;
isConnecting.value = false;
chatStore.connectionStatus = 'disconnected';
chatStore.socket = null;
// 自动重连
if (reconnectAttempts.value < maxReconnectAttempts) {
setTimeout(() => {
reconnectAttempts.value++;
reconnectDelay.value = Math.min(reconnectDelay.value * 2, 30_000);
console.log(
`尝试重连 (${reconnectAttempts.value}/${maxReconnectAttempts})`,
);
connectWebSocket();
}, reconnectDelay.value);
}
};
const handleError = (error) => {
console.error('WebSocket错误:', error);
isConnecting.value = false;
chatStore.connectionStatus = 'disconnected';
};
const handleCallSignal = (data) => {
console.log('收到通话信令:', data);
chatStore.handleCallSignal(data);
};
const bindUser = (userId) => {
if (!isConnected.value || !userId) return;
const bindMessage = {
request_type: 'bind',
user_type: 'doctor',
sender_user_id: `doctor-${userId}`,
};
send(bindMessage);
};
const send = (message) => {
if (!isConnected.value || !socket.value) {
console.error('WebSocket未连接无法发送消息');
return false;
}
try {
socket.value.send(JSON.stringify(message));
console.log('发送消息:', message);
return true;
} catch (error) {
console.error('发送消息失败:', error);
return false;
}
};
const sendMessage = (receiverUserId, messageType, content) => {
const message = {
request_type: 'send_message',
2025-07-22 16:55:09 +08:00
sender_user_id: userStore.currentUser?.doctor_id,
2025-07-19 16:47:52 +08:00
receiver_user_id: receiverUserId,
message_type: messageType,
message_content: content,
};
return send(message);
};
const sendCallSignal = (signal) => {
return send({
request_type: 'call_signal',
...signal,
2025-07-22 16:55:09 +08:00
sender_user_id: userStore.currentUser?.doctor_id,
2025-07-19 16:47:52 +08:00
});
};
const disconnect = () => {
if (socket.value) {
socket.value.close();
socket.value = null;
}
isConnected.value = false;
isConnecting.value = false;
chatStore.connectionStatus = 'disconnected';
chatStore.socket = null;
};
// 生成唯一ID
const generateCallId = () => {
return Date.now().toString() + Math.random().toString(36).slice(2, 11);
};
// onMounted(() => {
// connectWebSocket();
// });
onUnmounted(() => {
disconnect();
});
return {
socket,
isConnected,
isConnecting,
connectWebSocket,
disconnect,
send,
sendMessage,
sendCallSignal,
bindUser,
generateCallId,
};
}