Files
xk-admin/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts
lq 2423326951
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
fix: 聊天功能(部分)
2025-07-22 16:55:09 +08:00

192 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 = 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,
};
}