Files
xk-admin/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts
2025-12-24 16:05:21 +08:00

193 lines
5.1 KiB
TypeScript
Raw 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 { 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"
// const wsUrl = import.meta.env.VITE_WS_URL || 'ws://localhost:12080/ws';
const wsUrl = 'wss://api.ws.g.xiaokang88.com/ws';
// 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')
// 绑定当前用户
if (userStore.currentUser?.doctor_id) {
bindUser(userStore.currentUser.doctor_id);
}
};
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) {
chatStore.handleIncomingMessage(data, userStore.currentUser?.doctor_id);
}
} 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',
sender_user_id: userStore.currentUser?.doctor_id,
receiver_user_id: receiverUserId,
message_type: messageType,
message_content: content,
};
return send(message);
};
const sendCallSignal = (signal) => {
return send({
request_type: 'call_signal',
...signal,
sender_user_id: userStore.currentUser?.doctor_id,
});
};
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,
};
}