This commit is contained in:
Primakov Alexandr Alexandrovich
2025-10-12 23:15:09 +03:00
commit 09cdd06307
88 changed files with 15007 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
import { WebSocketMessage } from '../types';
const WS_URL = import.meta.env.VITE_WS_URL || 'ws://localhost:8000';
export class WebSocketClient {
private ws: WebSocket | null = null;
private listeners: Map<string, Set<(data: any) => void>> = new Map();
private reconnectAttempts = 0;
private maxReconnectAttempts = 5;
private reconnectDelay = 3000;
connect() {
if (this.ws?.readyState === WebSocket.OPEN) {
return;
}
try {
this.ws = new WebSocket(`${WS_URL}/ws/reviews`);
this.ws.onopen = () => {
console.log('WebSocket connected');
this.reconnectAttempts = 0;
this.notifyListeners('connection', { status: 'connected' });
};
this.ws.onmessage = (event) => {
try {
const message: WebSocketMessage = JSON.parse(event.data);
this.notifyListeners(message.type, message);
} catch (error) {
console.error('Failed to parse WebSocket message:', error);
}
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
this.notifyListeners('connection', { status: 'error', error });
};
this.ws.onclose = () => {
console.log('WebSocket disconnected');
this.notifyListeners('connection', { status: 'disconnected' });
this.reconnect();
};
} catch (error) {
console.error('Failed to create WebSocket:', error);
this.reconnect();
}
}
disconnect() {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
private reconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
console.log(`Reconnecting... Attempt ${this.reconnectAttempts}`);
setTimeout(() => this.connect(), this.reconnectDelay);
}
}
on(event: string, callback: (data: any) => void) {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set());
}
this.listeners.get(event)!.add(callback);
// Return unsubscribe function
return () => {
const callbacks = this.listeners.get(event);
if (callbacks) {
callbacks.delete(callback);
}
};
}
private notifyListeners(event: string, data: any) {
const callbacks = this.listeners.get(event);
if (callbacks) {
callbacks.forEach((callback) => callback(data));
}
}
send(message: any) {
if (this.ws?.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
} else {
console.warn('WebSocket is not connected');
}
}
}
// Create singleton instance
export const wsClient = new WebSocketClient();