You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

200 lines
5.0 KiB

class Ws {
constructor(ws, data, ...args) { // [{url, data, method...},,,,]
this._ws = ws;
this._data = data;
// 待发送的消息列
this._msgs = []
this.socket = this.doLink();
this.doOpen();
// 订阅/发布模型
this._events = {};
// 是否保持连接
this._isLink = true;
// 订阅列表(交易所专用)
this.subs = []
// 循环检查
setInterval(() => {
if (this._isLink) {
if (this.socket.readyState == 2 || this.socket.readyState == 3) {
this.resetLink()
}
}
}, 3000)
}
// 重连
resetLink() {
this.socket = this.doLink(() => {
this.Notify({
Event: 'resetLink'
});
this.resetSub()
});
this.doOpen();
}
// 连接
doLink(call) {
let ws = uni.connectSocket({
url: this._ws,
// 可选参数 设置默认值
header: {
'content-type': 'application/json'
},
method: 'GET',
success: () => {
call && call()
}
})
return ws;
}
doOpen() {
this.socket.onOpen((ev) => {
this.onOpen(ev)
})
this.socket.onMessage((ev) => {
this.onMessage(ev)
})
this.socket.onClose((ev) => {
this.onClose(ev)
})
this.socket.onError((ev) => {
this.onError(ev)
})
}
// 打开
onOpen() {
// 打开时重发未发出的消息
let list = Object.assign([], this._msgs)
list.forEach((item) => {
if (this.send(item)) {
let idx = this._msgs.indexOf(item)
if (idx != -1) {
this._msgs.splice(idx, 1)
}
}
})
}
// 手动关闭
doClose() {
this._isLink = false
this._events = {}
this._msgs = []
this.socket.close({
success: () => {
// console.log('socket close success')
}
})
}
// 添加监听
on(name, handler) {
this.subscribe(name, handler);
}
// 取消监听
off(name, handler) {
this.unsubscribe(name, handler);
}
// 关闭事件
onClose() {
// 是否重新连接
if (this._isLink) {
setTimeout(() => {
this.resetLink()
}, 3000)
}
}
// 错误
onError(evt) {
this.Notify({
Event: 'error',
Data: evt
});
}
// 接受数据
onMessage(evt) {
try {
// 解析推送的数据
const data = JSON.parse(evt.data);
// 通知订阅者
this.Notify({
Event: 'message',
Data: data
});
} catch (err) {
console.error(' >> Data parsing error:', err);
// 通知订阅者
this.Notify({
Event: 'error',
Data: err
});
}
}
// 订阅事件的方法
subscribe(name, handler) {
if (this._events.hasOwnProperty(name)) {
this._events[name].push(handler); // 追加事件
} else {
this._events[name] = [handler]; // 添加事件
}
}
// 取消订阅事件
unsubscribe(name, handler) {
let start = this._events[name].findIndex(item => item === handler);
// 删除该事件
this._events[name].splice(start, 1);
}
// 发布后通知订阅者
Notify(entry) {
// 检查是否有订阅者 返回队列
const cbQueue = this._events[entry.Event];
if (cbQueue && cbQueue.length) {
for (let callback of cbQueue) {
if (callback instanceof Function) callback(entry.Data);
}
}
}
// 发送消息
send(data) {
this.changeSubs(data)
if (this.socket.readyState == 1) {
this.socket.send({ data: JSON.stringify(data) })
return true
} else {
// 保存到待发送信息
if (!this._msgs.includes(data)) {
this._msgs.push(data)
};
return false
}
}
// 修改订阅列表(交易所用)
changeSubs(data) {
if (data.cmd == 'sub') {
if (!this.subs.includes(data.msg)) {
this.subs.push(data.msg)
}
} else if (data.cmd == 'unsub') {
let idx = this.subs.indexOf(data.msg)
if (idx != -1) {
this.subs.splice(idx, 1)
}
}
}
// 重新订阅(交易所用)
resetSub() {
let list = Object.assign([], this.subs)
list.forEach((item) => {
this.send({
cmd: 'sub',
msg: item
})
})
}
}
export default Ws