diff --git a/src/App.vue b/src/App.vue index 081f4db..09f28ef 100644 --- a/src/App.vue +++ b/src/App.vue @@ -8,6 +8,13 @@ saltutil.find_job jobs + {{ + !evtSource || evtSource.readyState == evtSource.CLOSED + ? 'Disconnected' + : evtSource.readyState == evtSource.OPEN + ? 'Connected' + : 'Connecting' + }} r.json()) - .then(r => { - const token: string = r.return[0].token; - this.evtSource = new EventSource(BASE_URL + 'events?token=' + token); - this.evtSource.onmessage = e => { - const event = JSON.parse(e.data); - event.splitTag = event.tag.split('/'); - this.events.push(event); + .then(r => this.connectEventSource(r.return[0].token)); + } - if (this.isEventType(event, 'job')) { - if (!(event.data.jid in this.jobs)) - this.$set(this.jobs, event.data.jid, []); - this.jobs[event.data.jid].push(event); - } - }; - }); + connectEventSource(token: string): void { + if (this.evtSourceTimeout) { + this.evtSourceTimeout = null; + } + + console.info('Connecting to eventSource.'); + this.evtSource = new EventSource(BASE_URL + 'events?token=' + token); + + this.evtSource.onopen = e => { + console.info('Connected to eventSource.'); + this.$forceUpdate(); // evtSource.readyState won't be detected otherwise + }; + + this.evtSource.onmessage = e => { + const event = JSON.parse(e.data); + event.splitTag = event.tag.split('/'); + this.events.push(event); + + if (this.isEventType(event, 'job')) { + if (!(event.data.jid in this.jobs)) + this.$set(this.jobs, event.data.jid, []); + this.jobs[event.data.jid].push(event); + } + }; + + this.evtSource.onerror = e => { + if (!this.evtSourceTimeout) { + console.info('Lost eventSource, reconnecting'); + console.info(e); + this.$forceUpdate(); // evtSource.readyState won't be detected otherwise + this.evtSource.close(); + this.evtSourceTimeout = window.setTimeout( + this.connectEventSource, + 1000, + token + ); + } + }; } isEventType(