| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import { EventSourcePolyfill } from "event-source-polyfill";
- class SseSource {
- private readonly url: URL
- private readonly onOpen: (() => void)
- private readonly onMessage: ((eventData: Array<any>) => void)
- private readonly onClose: (() => void)
- private readonly withCredentials: boolean
- protected eventSource: EventSource | null = null
- constructor(
- mercureHubBaseUrl: string,
- topic: string,
- onOpen: (() => void),
- onMessage: ((eventData: Array<any>) => void),
- onClose: (() => void),
- withCredentials: boolean = true
- ) {
- this.url = new URL(mercureHubBaseUrl)
- this.url.searchParams.append('topic', topic)
- this.onOpen = onOpen
- this.onMessage = onMessage
- this.onClose = onClose
- this.withCredentials = withCredentials
- }
- protected createEventSource(url: string, withCredentials: boolean): EventSourcePolyfill {
- return new EventSourcePolyfill(
- url,
- {
- withCredentials: withCredentials,
- heartbeatTimeout: 45 * 1000 // in ms, timeout can not be disabled yet, so I set it very large instead
- }
- );
- }
- public isConnected () {
- return this.eventSource !== null && this.eventSource.readyState === EventSourcePolyfill.OPEN
- }
- public subscribe () {
- if (this.isConnected()) {
- throw new Error('SSE - Already subscribed to this event source')
- }
- if (process.server) {
- throw new Error('SSE - Cannot subscribe on server side')
- }
- this.eventSource = this.createEventSource(this.url.toString(), this.withCredentials)
- this.eventSource.onerror = (event) => {
- console.error('SSE - An error happened')
- }
- this.eventSource.onopen = () => {
- console.log('SSE - Listening for events...')
- this.onOpen()
- }
- this.eventSource.onmessage = event => {
- const data = JSON.parse(event.data)
- this.onMessage(data)
- }
- }
- public unsubscribe () {
- if (this.eventSource === null || this.eventSource.readyState === EventSource.CLOSED) {
- return
- }
- this.eventSource.close()
- this.onClose()
- console.log('SSE - Subscription closed')
- }
- }
- export default SseSource
|