sozsoft-platform/ui/src/services/messenger.signalr.ts
2026-06-12 22:35:48 +03:00

119 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<MessageHandler>()
private messageDeletedHandlers = new Set<MessageDeletedHandler>()
private stateHandlers = new Set<StateHandler>()
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()