72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
import { create } from 'zustand'
|
|
|
|
type SSEState = {
|
|
source: EventSource | null
|
|
isConnected: boolean
|
|
connect: (steamId: string) => EventSource | undefined
|
|
disconnect: () => void
|
|
}
|
|
|
|
export const useSSE = create<SSEState>((set, get) => {
|
|
let reconnectTimeout: NodeJS.Timeout | null = null
|
|
|
|
const connect = (steamId: string): EventSource | undefined => {
|
|
const current = get().source
|
|
if (current) return current
|
|
|
|
const source = new EventSource(`http://localhost:3001/events?steamId=${steamId}`)
|
|
|
|
source.onopen = () => {
|
|
set({ source, isConnected: true })
|
|
}
|
|
|
|
source.onmessage = (event) => {
|
|
console.log('[SSE] Nachricht:', event.data)
|
|
}
|
|
|
|
source.addEventListener('notification', (event) => {
|
|
try {
|
|
const data = JSON.parse((event as MessageEvent).data)
|
|
window.dispatchEvent(new CustomEvent(`sse-${data.type}`, { detail: data }))
|
|
} catch (err) {
|
|
console.error('[SSE] Ungültige Nachricht:', event)
|
|
}
|
|
})
|
|
|
|
source.onerror = (err) => {
|
|
console.warn('[SSE] Verbindung verloren, versuche Reconnect...')
|
|
source.close()
|
|
set({ source: null, isConnected: false })
|
|
|
|
if (!reconnectTimeout) {
|
|
reconnectTimeout = setTimeout(() => {
|
|
reconnectTimeout = null
|
|
connect(steamId)
|
|
}, 3000)
|
|
}
|
|
}
|
|
|
|
set({ source })
|
|
return source // ✅ wichtig
|
|
}
|
|
|
|
const disconnect = () => {
|
|
const source = get().source
|
|
if (source) {
|
|
source.close()
|
|
}
|
|
if (reconnectTimeout) {
|
|
clearTimeout(reconnectTimeout)
|
|
reconnectTimeout = null
|
|
}
|
|
set({ source: null, isConnected: false })
|
|
}
|
|
|
|
return {
|
|
source: null,
|
|
isConnected: false,
|
|
connect,
|
|
disconnect,
|
|
}
|
|
})
|