2020-11-27 23:12:10 +01:00
|
|
|
<template>
|
|
|
|
<div/>
|
|
|
|
</template>
|
|
|
|
|
2020-11-21 01:12:08 +01:00
|
|
|
<script>
|
2020-11-22 12:57:28 +01:00
|
|
|
import { bus } from "@/bus";
|
|
|
|
|
2020-11-21 01:12:08 +01:00
|
|
|
export default {
|
|
|
|
name: "Events",
|
2020-11-22 12:57:28 +01:00
|
|
|
props: {
|
|
|
|
wsPort: {
|
|
|
|
type: Number,
|
|
|
|
default: 8009,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2020-11-21 01:12:08 +01:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
ws: null,
|
2020-11-28 00:29:22 +01:00
|
|
|
initialized: false,
|
2020-11-21 01:12:08 +01:00
|
|
|
pending: false,
|
|
|
|
opened: false,
|
|
|
|
timeout: null,
|
|
|
|
reconnectMsecs: 30000,
|
2020-11-22 12:57:28 +01:00
|
|
|
handlers: {},
|
2020-12-15 00:01:28 +01:00
|
|
|
handlerNameToEventTypes: {},
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
2020-11-22 12:57:28 +01:00
|
|
|
onWebsocketTimeout() {
|
2020-12-09 20:40:22 +01:00
|
|
|
console.log('Websocket reconnection timed out, retrying')
|
|
|
|
this.pending = false
|
|
|
|
if (this.ws)
|
|
|
|
this.ws.close()
|
|
|
|
|
|
|
|
this.onClose()
|
2020-11-22 12:57:28 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
onMessage(event) {
|
|
|
|
const handlers = []
|
|
|
|
event = event.data
|
|
|
|
|
|
|
|
if (typeof event === 'string') {
|
|
|
|
try {
|
|
|
|
event = JSON.parse(event)
|
|
|
|
} catch (e) {
|
|
|
|
console.warn('Received invalid non-JSON event')
|
|
|
|
console.warn(event)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.debug(event)
|
|
|
|
if (event.type !== 'event') {
|
|
|
|
// Discard non-event messages
|
2020-11-21 01:12:08 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-04-06 21:10:48 +02:00
|
|
|
if (null in this.handlers) { // lgtm [js/implicit-operand-conversion]
|
|
|
|
handlers.push(this.handlers[null]) // lgtm [js/implicit-operand-conversion]
|
2020-11-22 12:57:28 +01:00
|
|
|
}
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
if (event.args.type in this.handlers) {
|
2020-12-15 00:01:28 +01:00
|
|
|
handlers.push(...Object.values(this.handlers[event.args.type]))
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
|
|
|
|
2020-11-23 00:44:31 +01:00
|
|
|
for (let handler of handlers) {
|
2021-04-02 19:44:37 +02:00
|
|
|
if (!handler)
|
|
|
|
continue
|
|
|
|
|
2020-11-23 00:44:31 +01:00
|
|
|
if (handler instanceof Array)
|
|
|
|
handler = handler[0]
|
2021-04-02 19:44:37 +02:00
|
|
|
else if (handler instanceof Object && !(handler instanceof Function))
|
2021-03-27 12:26:55 +01:00
|
|
|
handler = Object.values(handler)[0]
|
2020-11-23 00:44:31 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
handler(event.args)
|
|
|
|
}
|
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
onOpen() {
|
|
|
|
if (this.opened) {
|
|
|
|
console.log("There's already an opened websocket connection, closing the newly opened one")
|
2020-12-09 20:40:22 +01:00
|
|
|
if (this.ws) {
|
|
|
|
this.ws.onclose = () => {}
|
|
|
|
this.ws.close()
|
|
|
|
}
|
2020-11-22 12:57:28 +01:00
|
|
|
}
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
console.log('Websocket connection successful')
|
|
|
|
this.opened = true
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
if (this.pending) {
|
|
|
|
this.pending = false
|
|
|
|
}
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
if (this.timeout) {
|
|
|
|
clearTimeout(this.timeout)
|
|
|
|
this.timeout = undefined
|
|
|
|
}
|
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
onError(error) {
|
|
|
|
console.error('Websocket error')
|
|
|
|
console.error(error)
|
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
onClose(event) {
|
|
|
|
if (event) {
|
|
|
|
console.log('Websocket closed - code: ' + event.code + ' - reason: ' + event.reason)
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
this.opened = false
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
if (!this.pending) {
|
|
|
|
this.pending = true
|
|
|
|
this.init()
|
|
|
|
}
|
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
init() {
|
|
|
|
try {
|
2021-01-30 23:21:52 +01:00
|
|
|
const protocol = location.protocol === 'https:' ? 'wss' : 'ws'
|
2020-11-22 12:57:28 +01:00
|
|
|
const url = `${protocol}://${location.hostname}:${this.wsPort}`
|
|
|
|
this.ws = new WebSocket(url)
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Websocket initialization error')
|
|
|
|
console.error(err)
|
|
|
|
return
|
|
|
|
}
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
this.pending = true
|
|
|
|
this.timeout = setTimeout(this.onWebsocketTimeout, this.reconnectMsecs)
|
|
|
|
this.ws.onmessage = this.onMessage
|
|
|
|
this.ws.onopen = this.onOpen
|
|
|
|
this.ws.onerror = this.onError
|
|
|
|
this.ws.onclose = this.onClose
|
2020-11-28 00:29:22 +01:00
|
|
|
this.initialized = true
|
2020-11-22 12:57:28 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
subscribe(msg) {
|
|
|
|
const handler = msg.handler
|
|
|
|
const events = msg.events.length ? msg.events : [null]
|
2020-12-15 00:01:28 +01:00
|
|
|
const handlerName = msg.handlerName
|
2020-11-22 12:57:28 +01:00
|
|
|
|
|
|
|
for (const event of events) {
|
|
|
|
if (!(event in this.handlers)) {
|
2020-12-15 00:01:28 +01:00
|
|
|
this.handlers[event] = {}
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
|
|
|
|
2020-12-15 00:01:28 +01:00
|
|
|
if (!(handlerName in this.handlerNameToEventTypes)) {
|
|
|
|
this.handlerNameToEventTypes[handlerName] = events
|
|
|
|
}
|
|
|
|
|
|
|
|
this.handlers[event][handlerName] = handler
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
this.unsubscribe(handlerName)
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
2020-11-22 12:57:28 +01:00
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-12-15 00:01:28 +01:00
|
|
|
unsubscribe(handlerName) {
|
|
|
|
const events = this.handlerNameToEventTypes[handlerName]
|
|
|
|
if (!events)
|
|
|
|
return
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
for (const event of events) {
|
2020-12-15 00:01:28 +01:00
|
|
|
if (!this.handlers[event]?.[handlerName])
|
2020-11-22 12:57:28 +01:00
|
|
|
continue
|
2020-11-21 01:12:08 +01:00
|
|
|
|
2020-12-15 00:01:28 +01:00
|
|
|
delete this.handlers[event][handlerName]
|
|
|
|
if (!Object.keys(this.handlers[event]).length)
|
2020-11-22 12:57:28 +01:00
|
|
|
delete this.handlers[event]
|
2020-11-21 01:12:08 +01:00
|
|
|
}
|
2020-12-15 00:01:28 +01:00
|
|
|
|
|
|
|
delete this.handlerNameToEventTypes[handlerName]
|
2020-11-22 12:57:28 +01:00
|
|
|
},
|
2020-11-21 01:12:08 +01:00
|
|
|
},
|
|
|
|
|
2020-11-22 12:57:28 +01:00
|
|
|
created() {
|
|
|
|
bus.on('subscribe', this.subscribe)
|
|
|
|
bus.on('unsubscribe', this.unsubscribe)
|
2020-11-21 01:12:08 +01:00
|
|
|
this.init()
|
|
|
|
},
|
|
|
|
}
|
|
|
|
</script>
|