import { Heart } from './heart.js'
import $config from '@/config';
export default class Socket extends Heart {
constructor(ops) {
super()
this.RECONNECT_TIMER = null
this.RECONNECT_COUNT = 10
this.OPTIONS = {
url: null,
heartTime: 5000,
heartMsg: 'ping',
isReconnect: true,
isRestory: true,
reconnectTime: 5000,
reconnectCount: 5,
openCb: null,
closeCb: null,
messageCb: null,
errorCb: null
}
Object.assign(this.OPTIONS, ops)
this.create()
}
create() {
window.WebSocket = window.WebSocket || window.MozWebSocket;
if(!window.WebSocket) {
new Error('当前浏览器不支持,无法使用')
return;
}
if(!this.OPTIONS.url){
new Error('链接地址不存在,无法建立ws通道')
}
delete this.ws
this.ws = new WebSocket(`ws://${$config.WS_API()}${this.OPTIONS.url}`)
this.onopen()
this.onclose()
this.onmessage()
}
onopen (callback) {
this.ws.onopen = () => {
clearTimeout(this.RECONNECT_TIMER)
this.OPTIONS.reconnectCount = this.RECONNECT_COUNT
super.reset().start(() => {
this.send(this.OPTIONS.heartMsg)
})
if (typeof callback === 'function') {
callback(event)
} else {
( typeof this.OPTIONS.openCb === 'function' ) && this.OPTIONS.openCb(event)
}
}
}
onclose (callback) {
this.ws.onclose = (event) => {
super.reset()
!this.OPTIONS.isRestory && this.onreconnect()
if (typeof callback == 'function') {
callback(event)
} else {
( typeof this.OPTIONS.openCb === 'function' ) && this.OPTIONS.closeCb(event)
}
}
}
onerror (callback) {
this.ws.onerror = (event) => {
if (typeof callback === 'function') {
callback(event)
} else {
(typeof this.OPTIONS.errorCb === 'function') && this.OPTIONS.errorCb(event)
}
}
}
onmessage (callback) {
this.ws.onmessage = (event) => {
super.reset().start(() => {
this.send(this.OPTIONS.heartMsg)
})
if (typeof callback === 'function') {
callback(event.data)
} else {
(typeof this.OPTIONS.messageCb === 'function') && this.OPTIONS.messageCb(event.data)
}
}
}
send (data) {
if (this.ws.readyState !== this.ws.OPEN) {
new Error('没有连接到服务器,无法推送')
return
}
this.ws.send(data)
}
onreconnect () {
if (this.OPTIONS.reconnectCount > 0 || this.OPTIONS.reconnectCount === -1) {
this.RECONNECT_TIMER = setTimeout( () => {
this.create()
if (this.OPTIONS.reconnectCount !== -1) {
this.OPTIONS.reconnectCount --
}
}, this.OPTIONS.reconnectTime)
} else {
clearTimeout(this.RECONNECT_TIMER)
this.OPTIONS.reconnectCount = this.RECONNECT_COUNT
}
}
destroy () {
super.reset()
clearTimeout(this.RECONNECT_TIMER)
this.OPTIONS.isRestory = true
this.ws.close()
}
}
heart文件:
export class Heart {
constructor() {
this.timeout = 5000
this.HEART_TIMEOUT = null
this.SERVER_HEART_TIMEOUT = null
}
reset() {
clearTimeout(this.HEART_TIMEOUT)
clearTimeout(this.SERVER_HEART_TIMEOUT)
return this
}
start(cb) {
this.HEART_TIMEOUT = setTimeout(() => {
cb()
this.SERVER_HEART_TIMEOUT = setTimeout(() => {
cb()
this.reset().start(cb())
}, this.timeout)
}, this.timeout)
}
}
|