134 lines
4.6 KiB
JavaScript
134 lines
4.6 KiB
JavaScript
export default class WebSocketClient {
|
|
|
|
constructor (url, options) {
|
|
this.instance = null
|
|
this.url = url
|
|
this.reconnects = 0
|
|
this.maxReconnects = options.maxReconnects || 10
|
|
this.reconnectInterval = options.reconnectInterval || 1000
|
|
this.store = options.store
|
|
this.wsData = []
|
|
this.timerId = 0
|
|
this.keepAliveTimeout = 1000
|
|
|
|
this.onOpen = null
|
|
this.onMessage = null
|
|
this.onClose = null
|
|
this.onError = null
|
|
this.blacklistMessages = [
|
|
"Metadata not available for",
|
|
"Klippy Request Timed Out",
|
|
"Klippy Host not connected",
|
|
]
|
|
this.blacklistFunctions = [
|
|
"getPowerDevices",
|
|
]
|
|
}
|
|
|
|
setUrl(url) {
|
|
this.url = url
|
|
}
|
|
|
|
createMessage (method, params, id) {
|
|
let msg = {
|
|
jsonrpc: '2.0', method: method, params: params, id: id
|
|
};
|
|
return JSON.stringify(msg)
|
|
}
|
|
|
|
passToStore (eventName, event) {
|
|
if (!eventName.startsWith('socket/')) { return }
|
|
let method = 'dispatch'
|
|
let target = eventName
|
|
let msg = event
|
|
if (event && event.data) {
|
|
msg = JSON.parse(event.data)
|
|
}
|
|
this.store[method](target, msg);
|
|
}
|
|
|
|
connect () {
|
|
this.store.dispatch("socket/setData", { isConnecting: true })
|
|
this.instance = new WebSocket(this.url)
|
|
|
|
this.instance.onopen = () => {
|
|
this.reconnects = 0
|
|
if (this.store) this.passToStore('socket/onOpen', event)
|
|
}
|
|
|
|
this.instance.onclose = (e) => {
|
|
this.passToStore('socket/onClose', e)
|
|
|
|
if (!e.wasClean && this.reconnects < this.maxReconnects) {
|
|
this.reconnects++
|
|
setTimeout(() => {
|
|
this.connect()
|
|
}, this.reconnectInterval)
|
|
} else {
|
|
this.store.dispatch("socket/setData", {
|
|
isConnecting: false,
|
|
connectingFailed: true
|
|
})
|
|
}
|
|
}
|
|
|
|
this.instance.onerror = () => {
|
|
this.instance.close()
|
|
}
|
|
|
|
this.instance.onmessage = (msg) => {
|
|
let data = JSON.parse(msg.data)
|
|
if (this.store) {
|
|
if (this.wsData.filter(item => item.id === data.id).length > 0 &&
|
|
this.wsData.filter(item => item.id === data.id)[0].action !== "") {
|
|
let tmpWsData = this.wsData.filter(item => item.id === data.id)[0]
|
|
|
|
if (data.error && data.error.message) {
|
|
if (
|
|
!this.blacklistMessages.find(element => data.error.message.startsWith(element)) &&
|
|
!this.blacklistFunctions.find(element => tmpWsData.action.startsWith(element))
|
|
) {
|
|
window.console.error("Response Error: "+tmpWsData.action+" > "+data.error.message);
|
|
|
|
this.store.dispatch(tmpWsData.action,
|
|
Object.assign(tmpWsData.actionPreload || {}, {
|
|
error: data.error,
|
|
requestParams: tmpWsData.params
|
|
})
|
|
)
|
|
}
|
|
} else {
|
|
let result = data.result
|
|
if (result === "ok") result = { result: result }
|
|
if (typeof(result) === "string") result = { result: result }
|
|
|
|
let preload = {}
|
|
let wsData = this.wsData.filter(item => item.id === data.id)[0]
|
|
if (wsData.actionPreload) Object.assign(preload, wsData.actionPreload)
|
|
Object.assign(preload, { requestParams: wsData.params })
|
|
Object.assign(preload, result)
|
|
this.store.dispatch(wsData.action, preload)
|
|
}
|
|
} else this.passToStore('socket/onMessage', data)
|
|
}
|
|
}
|
|
}
|
|
|
|
close() {
|
|
if (this.instance) this.instance.close()
|
|
}
|
|
|
|
sendObj (method, params, action = '', actionPreload = null) {
|
|
if (this.instance.readyState === WebSocket.OPEN) {
|
|
let id = Math.floor(Math.random() * 10000) + 1
|
|
this.wsData.push({
|
|
id: id,
|
|
action: action,
|
|
params: params,
|
|
actionPreload: actionPreload,
|
|
})
|
|
this.instance.send(this.createMessage(method, params, id))
|
|
}
|
|
}
|
|
}
|