import { store } from '@/store/store' import * as signalR from '@microsoft/signalr' import { MessengerAttachmentDto, MessengerMessageDeletedDto, MessengerMessageDto } from './messenger.service' export interface MessengerSendMessageDto { conversationId?: string recipientIds: string[] text?: string attachments: MessengerAttachmentDto[] } type MessageHandler = (message: MessengerMessageDto) => void type MessageDeletedHandler = (message: MessengerMessageDeletedDto) => void type StateHandler = (connected: boolean) => void class MessengerSignalRService { private connection?: signalR.HubConnection private messageHandlers = new Set() private messageDeletedHandlers = new Set() private stateHandlers = new Set() private createConnection() { const { auth } = store.getState() this.connection = new signalR.HubConnectionBuilder() .withUrl(`${import.meta.env.VITE_API_URL}/messengerhub`, { accessTokenFactory: () => store.getState().auth.session.token || auth.session.token || '', }) .withAutomaticReconnect() .configureLogging(signalR.LogLevel.Warning) .build() this.connection.on('MessengerMessageReceived', (message: MessengerMessageDto) => { this.messageHandlers.forEach((handler) => handler(message)) }) this.connection.on('MessengerMessageDeleted', (message: MessengerMessageDeletedDto) => { this.messageDeletedHandlers.forEach((handler) => handler(message)) }) this.connection.onreconnected(() => this.emitState(true)) this.connection.onreconnecting(() => this.emitState(false)) this.connection.onclose(() => this.emitState(false)) } async start() { if (!store.getState().auth.session.signedIn) return if (!this.connection) { this.createConnection() } if (this.connection?.state === signalR.HubConnectionState.Connected) { this.emitState(true) return } if (this.connection?.state === signalR.HubConnectionState.Connecting) return try { await this.connection?.start() this.emitState(true) } catch { this.emitState(false) } } async stop() { if (!this.connection) return await this.connection.stop() this.connection = undefined this.emitState(false) } async sendMessage(input: MessengerSendMessageDto) { await this.start() if (this.connection?.state !== signalR.HubConnectionState.Connected) { throw new Error('Messenger bağlantısı yok') } await this.connection.invoke('SendMessage', input) } async deleteMessage(messageId: string) { await this.start() if (this.connection?.state !== signalR.HubConnectionState.Connected) { throw new Error('Messenger baÄŸlantısı yok') } await this.connection.invoke('DeleteMessage', messageId) } onMessage(handler: MessageHandler) { this.messageHandlers.add(handler) return () => this.messageHandlers.delete(handler) } onMessageDeleted(handler: MessageDeletedHandler) { this.messageDeletedHandlers.add(handler) return () => this.messageDeletedHandlers.delete(handler) } onStateChange(handler: StateHandler) { this.stateHandlers.add(handler) handler(this.getConnectionState()) return () => this.stateHandlers.delete(handler) } getConnectionState() { return this.connection?.state === signalR.HubConnectionState.Connected } private emitState(connected: boolean) { this.stateHandlers.forEach((handler) => handler(connected)) } } export const messengerSignalR = new MessengerSignalRService()