diff --git a/client/src/store/index.ts b/client/src/store/index.ts index 20abbd9..9de0243 100644 --- a/client/src/store/index.ts +++ b/client/src/store/index.ts @@ -153,6 +153,12 @@ export default new Vuex.Store({ const res = await defaultApi.pullStop() return res.data }, + + async EVENTS_SSE(): Promise { + return new EventSource(configuration.basePath + '/api/events?sse', { + withCredentials: true, + }) + }, }, modules: { } diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue index 3fb7cfa..df6b4c2 100644 --- a/client/src/views/Home.vue +++ b/client/src/views/Home.vue @@ -83,9 +83,10 @@ export default class Home extends Vue { public dialog = false public interval!: number - public autoRefresh = 10 + public autoRefresh = 0 public autoRefreshItems = [ - { text: 'Off', value: 0 }, + { text: 'Off', value: -1 }, + { text: 'Live', value: 0 }, { text: '5s', value: 5 }, { text: '10s', value: 10 }, { text: '30s', value: 30 }, @@ -127,8 +128,11 @@ export default class Home extends Vue { window.clearInterval(this.interval) } - if (this.autoRefresh) { + if (this.autoRefresh > 0) { + this.sseClose() this.interval = window.setInterval(this.LoadRooms, this.autoRefresh * 1000) + } else if (this.autoRefresh == 0) { + this.sseStart() } } @@ -148,7 +152,62 @@ export default class Home extends Vue { } beforeDestroy() { - this.autoRefresh = 0 + this.autoRefresh = -1 + } + + sse: EventSource | null = null + sseIsOpen = false + sseReconnBackoff = 1000 + sseReconnRetries = 0 + + async sseStart(reconnect = false) { + if (!reconnect) { + this.sseIsOpen = true + } + + if (this.sse) { + this.sse.close() + } + + this.sse = await this.$store.dispatch('EVENTS_SSE') as EventSource + this.sseReconnRetries++ + + this.sse.addEventListener('rooms', (e) => { + console.log('SSE rooms', e) + this.LoadRooms() + }) + + this.sse.addEventListener('error', (e: Event) => { + console.log('SSE error', e) + + // if is closed, don't try to reconnect + if (!this.sseIsOpen) return + + const wait = this.sseReconnBackoff + 100 * this.sseReconnRetries + + // try to reconnect + setTimeout(() => { + this.sseStart(true) + }, wait) + + console.log('SSE error, trying to reconnect in ' + wait + 'ms') + }) + + this.sse.addEventListener('message', (e: Event) => { + console.log('SSE message', e) + }) + + this.sse.addEventListener('open', (e: Event) => { + console.log('SSE opened', e) + }) + } + + sseClose() { + if (this.sse) { + this.sse.close() + } + this.sse = null + this.sseIsOpen = false } } diff --git a/client/vue.config.js b/client/vue.config.js index 11235f2..7898efe 100644 --- a/client/vue.config.js +++ b/client/vue.config.js @@ -11,7 +11,9 @@ module.exports = defineConfig({ proxy: process.env.API_PROXY ? { '^/api': { target: process.env.API_PROXY, + timeout: 0, // because of SSE }, } : undefined, + compress: false, // because of SSE } })