import { store } from '@/store/store' import * as signalR from '@microsoft/signalr' import { MessengerAttachmentDto } from './messenger.service' export interface MessengerMessageDto { id: string tenantId?: string senderId: string senderUserName: string senderName: string recipientIds: string[] text?: string attachments: MessengerAttachmentDto[] sentAt: string } export interface MessengerSendMessageDto { recipientIds: string[] text?: string attachments: MessengerAttachmentDto[] } type MessageHandler = (message: MessengerMessageDto) => void type StateHandler = (connected: boolean) => void class MessengerSignalRService { private connection?: signalR.HubConnection private messageHandlers = 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.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) } onMessage(handler: MessageHandler) { this.messageHandlers.add(handler) return () => this.messageHandlers.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()