Files
system-file/web-vue/src/services/chat.js

106 lines
2.3 KiB
JavaScript

class ChatService {
constructor() {
this.ws = null
this.listeners = []
this.reconnectTimer = null
this.connected = false
this.connecting = false
this.pendingMessages = []
}
connect() {
if (this.ws && this.ws.readyState === WebSocket.OPEN) return
if (this.connecting) return
this.connecting = true
var token = localStorage.getItem('token')
if (!token) {
this.connecting = false
return
}
var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
var host = window.location.host
var wsUrl = protocol + '//' + host + '/ws/chat?token=' + token
try {
this.ws = new WebSocket(wsUrl)
} catch (e) {
this.connecting = false
return
}
var self = this
this.ws.onopen = function() {
self.connected = true
self.connecting = false
clearTimeout(self.reconnectTimer)
self.pendingMessages.forEach(function(msg) {
self.ws.send(JSON.stringify(msg))
})
self.pendingMessages = []
}
this.ws.onmessage = function(event) {
try {
var data = JSON.parse(event.data)
self.listeners.forEach(function(cb) {
cb(data)
})
} catch (e) {}
}
this.ws.onclose = function() {
self.connected = false
self.connecting = false
self.reconnectTimer = setTimeout(function() {
self.connect()
}, 3000)
}
this.ws.onerror = function() {}
}
send(data) {
if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
this.pendingMessages.push(data)
return true
}
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data))
return true
}
this.pendingMessages.push(data)
this.connect()
return true
}
onMessage(callback) {
var self = this
this.listeners.push(callback)
return function() {
self.listeners = self.listeners.filter(function(cb) {
return cb !== callback
})
}
}
disconnect() {
clearTimeout(this.reconnectTimer)
if (this.ws) {
this.ws.close()
this.ws = null
}
this.connected = false
this.connecting = false
this.pendingMessages = []
}
}
var chatService = new ChatService()
export { chatService }