格式化代码,websocket功能完善
This commit is contained in:
@@ -5,88 +5,88 @@ import { message } from "ant-design-vue";
|
||||
import router from "@/router";
|
||||
|
||||
const request = axios.create({
|
||||
timeout: 30000,
|
||||
baseURL: config.API_URL,
|
||||
timeout: 30000,
|
||||
baseURL: config.API_URL,
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
const userStore = useUserStore();
|
||||
const token = userStore.token;
|
||||
(config) => {
|
||||
const userStore = useUserStore();
|
||||
const token = userStore.token;
|
||||
|
||||
// 如果有 token,添加到请求头
|
||||
if (token) {
|
||||
config.headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
// 如果有 token,添加到请求头
|
||||
if (token) {
|
||||
config.headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
// 根据后端返回的数据结构进行处理
|
||||
// 后端返回格式为 { code, message, data }
|
||||
const { code, data, message: msg } = response.data;
|
||||
(response) => {
|
||||
// 根据后端返回的数据结构进行处理
|
||||
// 后端返回格式为 { code, message, data }
|
||||
const { code, data, message: msg } = response.data;
|
||||
|
||||
// 请求成功
|
||||
if (code === 200 || code === 1) {
|
||||
return { code, data, message: msg };
|
||||
}
|
||||
// 请求成功
|
||||
if (code === 200 || code === 1) {
|
||||
return { code, data, message: msg };
|
||||
}
|
||||
|
||||
// 其他错误码处理
|
||||
message.error(msg || "请求失败");
|
||||
return Promise.reject(new Error(msg || "请求失败"));
|
||||
},
|
||||
async (error) => {
|
||||
const userStore = useUserStore();
|
||||
const { response } = error;
|
||||
// 其他错误码处理
|
||||
message.error(msg || "请求失败");
|
||||
return Promise.reject(new Error(msg || "请求失败"));
|
||||
},
|
||||
async (error) => {
|
||||
const userStore = useUserStore();
|
||||
const { response } = error;
|
||||
|
||||
// 无响应(网络错误、超时等)
|
||||
if (!response) {
|
||||
message.error("网络错误,请检查网络连接");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// 无响应(网络错误、超时等)
|
||||
if (!response) {
|
||||
message.error("网络错误,请检查网络连接");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
const { status, data } = response;
|
||||
const { status, data } = response;
|
||||
|
||||
// 401 未授权 - token 过期或无效
|
||||
if (status === 401) {
|
||||
// 直接登出并跳转到登录页
|
||||
userStore.logout();
|
||||
router.push("/login");
|
||||
message.error("登录已过期,请重新登录");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// 401 未授权 - token 过期或无效
|
||||
if (status === 401) {
|
||||
// 直接登出并跳转到登录页
|
||||
userStore.logout();
|
||||
router.push("/login");
|
||||
message.error("登录已过期,请重新登录");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// 403 禁止访问
|
||||
if (status === 403) {
|
||||
message.error("没有权限访问该资源");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// 403 禁止访问
|
||||
if (status === 403) {
|
||||
message.error("没有权限访问该资源");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// 404 资源不存在
|
||||
if (status === 404) {
|
||||
message.error("请求的资源不存在");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// 404 资源不存在
|
||||
if (status === 404) {
|
||||
message.error("请求的资源不存在");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// 500 服务器错误
|
||||
if (status >= 500) {
|
||||
message.error("服务器错误,请稍后重试");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// 500 服务器错误
|
||||
if (status >= 500) {
|
||||
message.error("服务器错误,请稍后重试");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// 其他错误
|
||||
const errorMessage = data?.message || error.message || "请求失败";
|
||||
message.error(errorMessage);
|
||||
return Promise.reject(error);
|
||||
},
|
||||
// 其他错误
|
||||
const errorMessage = data?.message || error.message || "请求失败";
|
||||
message.error(errorMessage);
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
export default request;
|
||||
|
||||
@@ -5,255 +5,391 @@
|
||||
*/
|
||||
|
||||
class WebSocketClient {
|
||||
constructor(url, options = {}) {
|
||||
this.url = url
|
||||
this.ws = null
|
||||
this.reconnectAttempts = 0
|
||||
this.maxReconnectAttempts = options.maxReconnectAttempts || 5
|
||||
this.reconnectInterval = options.reconnectInterval || 3000
|
||||
this.reconnectDelay = options.reconnectDelay || 1000
|
||||
this.heartbeatInterval = options.heartbeatInterval || 30000
|
||||
this.heartbeatTimer = null
|
||||
this.isManualClose = false
|
||||
this.isConnecting = false
|
||||
constructor(url, options = {}) {
|
||||
this.url = url;
|
||||
this.ws = null;
|
||||
this.reconnectAttempts = 0;
|
||||
this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
|
||||
this.reconnectInterval = options.reconnectInterval || 3000;
|
||||
this.reconnectDelay = options.reconnectDelay || 1000;
|
||||
this.heartbeatInterval = options.heartbeatInterval || 30000;
|
||||
this.heartbeatTimer = null;
|
||||
this.isManualClose = false;
|
||||
this.isConnecting = false;
|
||||
|
||||
// Event handlers
|
||||
this.onOpen = options.onOpen || null
|
||||
this.onMessage = options.onMessage || null
|
||||
this.onError = options.onError || null
|
||||
this.onClose = options.onClose || null
|
||||
// Event handlers
|
||||
this.onOpen = options.onOpen || null;
|
||||
this.onMessage = options.onMessage || null;
|
||||
this.onError = options.onError || null;
|
||||
this.onClose = options.onClose || null;
|
||||
|
||||
// Message handlers
|
||||
this.messageHandlers = new Map()
|
||||
}
|
||||
// Message handlers
|
||||
this.messageHandlers = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to WebSocket server
|
||||
*/
|
||||
connect() {
|
||||
if (this.isConnecting || (this.ws && this.ws.readyState === WebSocket.OPEN)) {
|
||||
return
|
||||
}
|
||||
/**
|
||||
* Get connection state description
|
||||
*/
|
||||
getConnectionState() {
|
||||
if (!this.ws) return "CLOSED";
|
||||
switch (this.ws.readyState) {
|
||||
case WebSocket.CONNECTING:
|
||||
return "CONNECTING";
|
||||
case WebSocket.OPEN:
|
||||
return "OPEN";
|
||||
case WebSocket.CLOSING:
|
||||
return "CLOSING";
|
||||
case WebSocket.CLOSED:
|
||||
return "CLOSED";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
this.isConnecting = true
|
||||
this.isManualClose = false
|
||||
/**
|
||||
* Connect to WebSocket server
|
||||
*/
|
||||
connect() {
|
||||
if (
|
||||
this.isConnecting ||
|
||||
(this.ws && this.ws.readyState === WebSocket.OPEN)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.ws = new WebSocket(this.url)
|
||||
this.isConnecting = true;
|
||||
this.isManualClose = false;
|
||||
|
||||
this.ws.onopen = (event) => {
|
||||
console.log('WebSocket connected', event)
|
||||
this.isConnecting = false
|
||||
this.reconnectAttempts = 0
|
||||
try {
|
||||
this.ws = new WebSocket(this.url);
|
||||
|
||||
// Start heartbeat
|
||||
this.startHeartbeat()
|
||||
this.ws.onopen = (event) => {
|
||||
console.log("WebSocket connected", event);
|
||||
this.isConnecting = false;
|
||||
this.reconnectAttempts = 0;
|
||||
|
||||
// Call onOpen handler
|
||||
if (this.onOpen) {
|
||||
this.onOpen(event)
|
||||
}
|
||||
}
|
||||
// Start heartbeat
|
||||
this.startHeartbeat();
|
||||
|
||||
this.ws.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data)
|
||||
console.log('WebSocket message received', message)
|
||||
// Call onOpen handler
|
||||
if (this.onOpen) {
|
||||
this.onOpen(event);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle different message types
|
||||
this.handleMessage(message)
|
||||
this.ws.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
console.log("WebSocket message received", message);
|
||||
|
||||
// Call onMessage handler
|
||||
if (this.onMessage) {
|
||||
this.onMessage(message, event)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to parse WebSocket message', error)
|
||||
}
|
||||
}
|
||||
// Handle different message types
|
||||
this.handleMessage(message);
|
||||
|
||||
this.ws.onerror = (error) => {
|
||||
console.error('WebSocket error', error)
|
||||
this.isConnecting = false
|
||||
// Call onMessage handler
|
||||
if (this.onMessage) {
|
||||
this.onMessage(message, event);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to parse WebSocket message", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat()
|
||||
this.ws.onerror = (error) => {
|
||||
console.error("WebSocket error", error);
|
||||
this.isConnecting = false;
|
||||
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error)
|
||||
}
|
||||
}
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat();
|
||||
|
||||
this.ws.onclose = (event) => {
|
||||
console.log('WebSocket closed', event)
|
||||
this.isConnecting = false
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat()
|
||||
this.ws.onclose = (event) => {
|
||||
console.log("WebSocket closed", event);
|
||||
this.isConnecting = false;
|
||||
|
||||
// Call onClose handler
|
||||
if (this.onClose) {
|
||||
this.onClose(event)
|
||||
}
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat();
|
||||
|
||||
// Attempt to reconnect if not manually closed
|
||||
if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnect()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to create WebSocket connection', error)
|
||||
this.isConnecting = false
|
||||
// Call onClose handler
|
||||
if (this.onClose) {
|
||||
this.onClose(event);
|
||||
}
|
||||
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Attempt to reconnect if not manually closed
|
||||
if (
|
||||
!this.isManualClose &&
|
||||
this.reconnectAttempts < this.maxReconnectAttempts
|
||||
) {
|
||||
this.reconnect();
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Failed to create WebSocket connection", error);
|
||||
this.isConnecting = false;
|
||||
|
||||
/**
|
||||
* Reconnect to WebSocket server
|
||||
*/
|
||||
reconnect() {
|
||||
if (this.isConnecting || this.reconnectAttempts >= this.maxReconnectAttempts) {
|
||||
console.log('Max reconnection attempts reached')
|
||||
return
|
||||
}
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.reconnectAttempts++
|
||||
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1)
|
||||
/**
|
||||
* Reconnect to WebSocket server
|
||||
*/
|
||||
reconnect() {
|
||||
if (
|
||||
this.isConnecting ||
|
||||
this.reconnectAttempts >= this.maxReconnectAttempts
|
||||
) {
|
||||
console.log("Max reconnection attempts reached");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Reconnecting attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`)
|
||||
this.reconnectAttempts++;
|
||||
const delay =
|
||||
this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
||||
|
||||
setTimeout(() => {
|
||||
this.connect()
|
||||
}, delay)
|
||||
}
|
||||
console.log(
|
||||
`Reconnecting attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`,
|
||||
);
|
||||
|
||||
/**
|
||||
* Disconnect from WebSocket server
|
||||
*/
|
||||
disconnect() {
|
||||
this.isManualClose = true
|
||||
this.stopHeartbeat()
|
||||
setTimeout(() => {
|
||||
this.connect();
|
||||
}, delay);
|
||||
}
|
||||
|
||||
if (this.ws) {
|
||||
this.ws.close()
|
||||
this.ws = null
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Disconnect from WebSocket server
|
||||
*/
|
||||
disconnect() {
|
||||
this.isManualClose = true;
|
||||
this.stopHeartbeat();
|
||||
|
||||
/**
|
||||
* Send message to server
|
||||
*/
|
||||
send(type, data = {}) {
|
||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
const message = JSON.stringify({
|
||||
type,
|
||||
data
|
||||
})
|
||||
this.ws.send(message)
|
||||
console.log('WebSocket message sent', { type, data })
|
||||
} else {
|
||||
console.warn('WebSocket is not connected')
|
||||
}
|
||||
}
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle incoming messages
|
||||
*/
|
||||
handleMessage(message) {
|
||||
const { type, data } = message
|
||||
/**
|
||||
* Send message to server
|
||||
*/
|
||||
send(type, data = {}) {
|
||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
const message = JSON.stringify({
|
||||
type,
|
||||
data,
|
||||
});
|
||||
this.ws.send(message);
|
||||
console.log("WebSocket message sent", { type, data });
|
||||
} else {
|
||||
console.warn("WebSocket is not connected");
|
||||
}
|
||||
}
|
||||
|
||||
// Get handler for this message type
|
||||
const handler = this.messageHandlers.get(type)
|
||||
if (handler) {
|
||||
handler(data)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Handle incoming messages
|
||||
*/
|
||||
handleMessage(message) {
|
||||
const { type, data } = message;
|
||||
|
||||
/**
|
||||
* Register message handler
|
||||
*/
|
||||
on(messageType, handler) {
|
||||
this.messageHandlers.set(messageType, handler)
|
||||
}
|
||||
// Get handler for this message type
|
||||
const handler = this.messageHandlers.get(type);
|
||||
if (handler) {
|
||||
handler(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister message handler
|
||||
*/
|
||||
off(messageType) {
|
||||
this.messageHandlers.delete(messageType)
|
||||
}
|
||||
/**
|
||||
* Register message handler
|
||||
*/
|
||||
on(messageType, handler) {
|
||||
this.messageHandlers.set(messageType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start heartbeat
|
||||
*/
|
||||
startHeartbeat() {
|
||||
this.stopHeartbeat()
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
this.send('heartbeat', { timestamp: Date.now() })
|
||||
}, this.heartbeatInterval)
|
||||
}
|
||||
/**
|
||||
* Unregister message handler
|
||||
*/
|
||||
off(messageType) {
|
||||
this.messageHandlers.delete(messageType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop heartbeat
|
||||
*/
|
||||
stopHeartbeat() {
|
||||
if (this.heartbeatTimer) {
|
||||
clearInterval(this.heartbeatTimer)
|
||||
this.heartbeatTimer = null
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Start heartbeat
|
||||
*/
|
||||
startHeartbeat() {
|
||||
this.stopHeartbeat();
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
this.send("heartbeat", { timestamp: Date.now() });
|
||||
}, this.heartbeatInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection state
|
||||
*/
|
||||
get readyState() {
|
||||
if (!this.ws) return WebSocket.CLOSED
|
||||
return this.ws.readyState
|
||||
}
|
||||
/**
|
||||
* Stop heartbeat
|
||||
*/
|
||||
stopHeartbeat() {
|
||||
if (this.heartbeatTimer) {
|
||||
clearInterval(this.heartbeatTimer);
|
||||
this.heartbeatTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if connected
|
||||
*/
|
||||
get isConnected() {
|
||||
return this.ws && this.ws.readyState === WebSocket.OPEN
|
||||
}
|
||||
/**
|
||||
* Get connection state
|
||||
*/
|
||||
get readyState() {
|
||||
if (!this.ws) return WebSocket.CLOSED;
|
||||
return this.ws.readyState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if connected
|
||||
*/
|
||||
get isConnected() {
|
||||
return this.ws && this.ws.readyState === WebSocket.OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create WebSocket connection
|
||||
*/
|
||||
export function createWebSocket(userId, token, options = {}) {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
|
||||
// 优先使用配置的 WS_URL,否则使用当前域名
|
||||
const host = options.wsUrl || window.location.host
|
||||
const url = `${protocol}//${host}/ws?user_id=${userId}&token=${token}`
|
||||
// 优先使用配置的 WS_URL,否则使用当前域名
|
||||
const host = options.wsUrl || window.location.host;
|
||||
const url = `${protocol}//${host}/ws?user_id=${userId}&token=${token}`;
|
||||
|
||||
return new WebSocketClient(url, options)
|
||||
return new WebSocketClient(url, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket singleton instance
|
||||
* WebSocket singleton instance with connection management
|
||||
*/
|
||||
let wsClient = null
|
||||
let wsClient = null;
|
||||
let currentUserId = null;
|
||||
let currentToken = null;
|
||||
let pendingConnection = null;
|
||||
|
||||
export function getWebSocket(userId, token, options = {}) {
|
||||
if (!wsClient || !wsClient.isConnected) {
|
||||
wsClient = createWebSocket(userId, token, options)
|
||||
}
|
||||
return wsClient
|
||||
// Check if we have a connection for the same user
|
||||
if (wsClient) {
|
||||
// If connection exists and user/token matches
|
||||
if (currentUserId === userId && currentToken === token) {
|
||||
const state = wsClient.getConnectionState();
|
||||
|
||||
// If already connected or connecting, return existing instance
|
||||
if (state === "OPEN" || state === "CONNECTING") {
|
||||
console.log("WebSocket: Reusing existing connection", {
|
||||
state,
|
||||
userId: currentUserId,
|
||||
});
|
||||
return wsClient;
|
||||
}
|
||||
|
||||
// If connection is closed or closing, clean up
|
||||
if (state === "CLOSED" || state === "CLOSING") {
|
||||
console.log("WebSocket: Cleaning up closed connection");
|
||||
if (wsClient.ws) {
|
||||
wsClient.ws.onopen = null;
|
||||
wsClient.ws.onmessage = null;
|
||||
wsClient.ws.onerror = null;
|
||||
wsClient.ws.onclose = null;
|
||||
wsClient.ws = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Different user/token, disconnect old connection
|
||||
if (currentUserId !== userId || currentToken !== token) {
|
||||
console.log(
|
||||
"WebSocket: User changed, disconnecting old connection",
|
||||
);
|
||||
if (wsClient) {
|
||||
wsClient.disconnect();
|
||||
}
|
||||
wsClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there's a pending connection
|
||||
if (pendingConnection) {
|
||||
return new Promise((resolve) => {
|
||||
const checkPending = setInterval(() => {
|
||||
if (!pendingConnection) {
|
||||
clearInterval(checkPending);
|
||||
console.log("WebSocket: Pending connection completed");
|
||||
resolve(getWebSocket(userId, token, options));
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
// Create new connection
|
||||
console.log("WebSocket: Creating new connection", {
|
||||
userId,
|
||||
token: token ? "***" : null,
|
||||
});
|
||||
currentUserId = userId;
|
||||
currentToken = token;
|
||||
|
||||
pendingConnection = true;
|
||||
wsClient = createWebSocket(userId, token, options);
|
||||
|
||||
// Mark connection as no longer pending when connected or failed
|
||||
const originalOnOpen = wsClient.onOpen;
|
||||
const originalOnError = wsClient.onError;
|
||||
const originalOnClose = wsClient.onClose;
|
||||
|
||||
wsClient.onOpen = (event) => {
|
||||
pendingConnection = null;
|
||||
console.log("WebSocket: Connection established", { userId });
|
||||
if (originalOnOpen) originalOnOpen(event);
|
||||
};
|
||||
|
||||
wsClient.onError = (error) => {
|
||||
pendingConnection = null;
|
||||
console.error("WebSocket: Connection error", { userId, error });
|
||||
if (originalOnError) originalOnError(error);
|
||||
};
|
||||
|
||||
wsClient.onClose = (event) => {
|
||||
pendingConnection = null;
|
||||
console.log("WebSocket: Connection closed", {
|
||||
userId,
|
||||
code: event.code,
|
||||
reason: event.reason,
|
||||
});
|
||||
if (originalOnClose) originalOnClose(event);
|
||||
};
|
||||
|
||||
return wsClient;
|
||||
}
|
||||
|
||||
export function closeWebSocket() {
|
||||
if (wsClient) {
|
||||
wsClient.disconnect()
|
||||
wsClient = null
|
||||
}
|
||||
if (wsClient) {
|
||||
console.log("WebSocket: Closing connection manually");
|
||||
wsClient.disconnect();
|
||||
|
||||
// Clean up event handlers
|
||||
if (wsClient.ws) {
|
||||
wsClient.ws.onopen = null;
|
||||
wsClient.ws.onmessage = null;
|
||||
wsClient.ws.onerror = null;
|
||||
wsClient.ws.onclose = null;
|
||||
wsClient.ws = null;
|
||||
}
|
||||
|
||||
wsClient = null;
|
||||
currentUserId = null;
|
||||
currentToken = null;
|
||||
pendingConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default WebSocketClient
|
||||
export default WebSocketClient;
|
||||
|
||||
Reference in New Issue
Block a user