import { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr'; export interface SocketCompat { on(event: string, callback: (...args: any[]) => void): void; off(event: string, callback?: (...args: any[]) => void): void; emit(event: string, ...args: any[]): void; disconnect(): void; status: string; } let connection: HubConnection | null = null; let socketWrapper: SocketCompat | null = null; export function connectSocket(token: string): SocketCompat { if (connection && (connection.state === 'Connected' || connection.state === 'Connecting')) { return socketWrapper!; } connection = new HubConnectionBuilder() .withUrl('/hubs/chat', { accessTokenFactory: () => token }) .withAutomaticReconnect() .configureLogging(LogLevel.Information) .build(); // Обертка для совместимости с Socket.io API socketWrapper = { on: (event: string, callback: (...args: any[]) => void) => { connection?.on(event, callback); }, off: (event: string, callback?: (...args: any[]) => void) => { if (callback) { connection?.off(event, callback); } else { connection?.off(event); } }, emit: (event: string, ...args: any[]) => { if (connection?.state === 'Connected') { // В SignalR invoke возвращает Promise, но Socket.io emit - нет. // Мы просто запускаем и логируем ошибки. connection.invoke(event, ...args).catch(err => console.error(`SignalR emit error (${event}):`, err)); } else { console.warn(`SignalR emit skipped (${event}): connection state is ${connection?.state}`); } }, disconnect: () => { connection?.stop(); }, get status() { return connection?.state || 'Disconnected'; } }; connection.start() .then(() => console.log('SignalR подключён')) .catch(err => console.error('Ошибка подключения SignalR:', err.toString())); return socketWrapper; } export function getSocket(): SocketCompat | null { return socketWrapper; } export function disconnectSocket() { if (connection) { connection.stop(); connection = null; socketWrapper = null; } }